7

The goal is to have the member variable _AddValue point to the CreateFirstValue function upon class initialization and after the first invocation of AddValue, all future calls to it will invoke CreateAnotherValue.

Previously, I just had a single AddValue function with a conditional check to determine which function to call. However, I feel like that implementation is flawed because that if check will occur every time and it seems like a function pointer would be beneficial here.

An example:

class Foo
{
 private:
  int _value;
  void (*_AddValue)(int value); // Pointer to function member variable

  void CreateFirstValue(int value)
  {
    _value = value;
    _AddValue = &CreateAnotherValue;
  }

  void CreateAnotherValue(int value)
  {
    // This function will create values differently.
    _value = ...;
  }

 public:
  // Constructor
  Foo()
   : _value(0), _AddValue(CreateFirstValue)
  {
  }

  AddValue(int value) // This function is called by the user.
  {
    _AddValue(value);
  }
};

The code above is not the actual code, just an example of what I'm trying to accomplish.

right now I'm getting an error: argument of type void (BTree::)(int) does not match void (*)(int)

6
  • This code looks right to me, what is your issue? Commented Jun 15, 2012 at 19:50
  • The first error says "argument of type void (BTree::)(int) does not match void (*)(int)" I'm assuming I need to use the address-of operator, but when I add that, I get "ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function." Commented Jun 15, 2012 at 19:52
  • try _AddValue(0) in your cctor, and then within the body, _AddValue = CreateFirstValue. Commented Jun 15, 2012 at 19:58
  • @Hans: No can do, there is no decay from function name to pointer-to-member. You need to use the address-of operator, and that requires a qualified name. And works just fine inside the ctor-initializer-list. Commented Jun 15, 2012 at 20:08
  • No need to add "homework" to the title if the question is tagged as such. Edited. Commented Jun 15, 2012 at 20:20

2 Answers 2

15
&CreateAnotherValue

This syntax is not valid. To create a pointer-to-member, you have to name the class, even from inside other members. Try

&Foo::CreateAnotherValue

In this case you are talking the address of a qualified non-static member function, which is allowed and prevents the error about address of unqualified member function.

Of course, you then need an appropriately typed variable to store the pointer-to-member in, see Bo's answer for the correct declaration. When it comes time to call it, you will need to use the pointer-to-member-dereference operator (either .* or ->*), so say

(this->*_AddValue)(whatever);

The same rule applies to data, if you say &Foo::_value, you get a pointer-to-member of type int Foo::*. But in the data case, the unqualified name is also accepted, but with very different behavior. &_value gives a normal pointer, type int*, which is the address of the specific _value member variable inside the this instance.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the excellent explanation. I knew I had the general gist of all this right, just implementation was weird for me. Especially because our text book doesn't go into much depth with regards to function pointers. With your explanation and Bo's example, it's not compiling. Thank you!
Comment above should say ...it's now compiling... (=
7

  void (*_AddValue)(int value); // Pointer to function member variable

This is not really a pointer-to-member, but a pointer to a free function.

You need to make this

void (Foo::*_AddValue)(int value); // Pointer to function member variable

4 Comments

@BoPersson With that change, I'm getting "btree.cpp: In constructor BTree::BTree():" "btree.cpp:9:21: error: argument of type void (BTree::)(int) does not match void (BTree::*)(int)"
@fhaddad - You might need to use &Foo::CreateAnotherValue to take the address of the member function. That would match the Foo::* of the pointer.
with your help and Ben's it's not compiling. I knew it was syntax issues. I'm still quite confused on how one understands how all this stuff works. Lots of time when I am reading the compiler errors, I don't understand what they are saying.
Comment above should say ...it's now compiling... (=

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.