Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm starting with a short introduction of what I know from the C language:

  • a pointer is a type that stores an adress or a NULL
  • the * operator reads the left value of the variable on its right and use this value as address and reads the value of the variable at that address
  • the & operator generate a pointer to the variable on its right

So I was thinking that in C++ the pointers can work this way too, but I was wrong. To generate a pointer to a static method I have to do this:

#include <iostream>

class Foo{
    public:
    static void dummy(void){ std::cout << "I'm dummy" << std::endl; };
};

int main(){
    void (*p)();
    p = Foo::dummy; // step 1
    p();
    p = &(Foo::dummy); // step 2
    p();
    p = Foo; // step 3
    p->dummy();
    return(0);
}

Now I have several questions:

  • Why does step 1 work?
  • Why does step 2 work too? Looks like a "pointer to pointer" for p to me, very different from step 1.
  • Why is step 3 the only one that doesn't work, and is the only one that makes some sort of sense to me, honestly?
  • How can I write an array of pointers or a pointer to pointers structure to store methods (static or non-static from real objects)?
  • What is the best syntax and coding style for generating a pointer to a method?
share|improve this question

2 Answers 2

up vote 12 down vote accepted

what is the best syntax and coding style for generating a pointer to a method?

Don't. Use std::function<void()>.

Now, on to the steps. Step 1 is technically illegal, but your compiler allowed it by implicitly taking the address for you. Step 2 is how it should be done. The name of a static function (in this case, Foo::dummy) is a function lvalue and must have it's address taken to be legal C++ and yield a function pointer.

Step 3 simply doesn't make any sense at all. You're trying to assign ... a run-time function pointer ... to a type? That makes no sense whatsoever. And then you try to access ... a member ... of a function pointer? Does not compute.

There are two parts to the answer "What do I do when I want to X in C++?". The first part, for C veterans only, is "Forget whatever you think you learned in C". The second part is about doing X.

how can i write an array of pointers or a pointer to pointers structure to store methods ( static or non-static from real objects )

std::vector<std::function<void()>> arr;

le done.

share|improve this answer
1  
Function to function-pointer conversion is a standard conversion (including for static member functions) (§4.3), I'm pretty sure step 1 is entirely valid (and identical to step 2 in semantics). –  Mat Jun 24 '12 at 5:36
    
@Mat: That's what I thought. Otherwise, C++ would break C backwards compatibility for no good reason. –  tdammers Jun 24 '12 at 9:06

what is the best syntax and coding style for generating a pointer to a method?

According to C++ Faq lite's paragraph about "Pointers to member functions", in general you should use a typedef to create the pointer, and a macro when calling the member function (points 33.5 and 33.6 respectively).
This makes it simpler to call the method on a given object.

In your example you are using a static method, so you don't need an object to call it.
However here is what your code would look like following these recommendations, when calling a non static member function :

// define the macro to use pointer to methods
#define CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))

class Foo{
    public:
    void dummy1(void){ std::cout << "I'm dummy 1" << std::endl; };
    void dummy2(void){ std::cout << "I'm dummy 2" << std::endl; };
};

int main(){
    // define the PointerToFooMember type. Note that you can use it for dummy1 and dummy2 as well
    typedef void(Foo::*PointerToFooMember)();
    PointerToFooMember ptr = &Foo::dummy1;

    // create an object to call the method later
    Foo foo;

    // call the method
    CALL_MEMBER_FN(foo, ptr)();
}
share|improve this answer
    
-1 for needless macro and poor use of Standard facilities. L2 std::bind. –  DeadMG Jun 24 '12 at 2:54
    
In some environments (embedded for example), you sometimes have less access to the std functions (including std::bind), so the macro version could be helpful to some people. However I would be very interested if you could provide us a version of the above code sample rewritten using std::bind. –  wil Jun 24 '12 at 2:59
1  
Should be roughly like std::bind(ptr, foo). Maybe a std::ref in there if you want to refer to foo instead of copy. As for embedded, it makes up barely over 1% of the software industry. It's not applicable to general-case answers. If you don't specify limitations on the Standard library in the question, they do not exist. Oh, and the macro could be replaced with a template, not to mention that it's less verbose without, so even if you don't have std::bind it's very poor. –  DeadMG Jun 24 '12 at 3:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.