2
#include <iostream>
#include <functional>

class Foo 
{
    public:
    Foo(int value)
    : value_(value){}
    void print()
    {
        std::cout << "member print: " << value_ << std::endl;
    }
    int value_;
};

void print()
{
    std::cout << "stand alone print" << std::endl;
}

template<typename F>
void execute(F&& f)
{
    f();
}

int main()
{ 

    execute(print);

    Foo foo(5);

    auto binded = std::bind(&Foo::print,foo);
    execute(binded);

    //auto Foo::* foo_print = &Foo::print;
    //execute(foo.*foo_print);

}

The code above compiles and runs fine.

But if the last part, which uses the pointers to the print member function, is uncommented, then compilation fails with:

error: invalid use of non-static member function of type ‘void (Foo::)()’ 

Is there a syntax error in the code, or is this an impossibility for some reason?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Vince
  • 3,979
  • 10
  • 41
  • 69
  • An actual pointer to a member function is, at the assembly level, the same as a pointer to an ordinary function. Therefore, to call it, you must somehow bind the object. – Michael Chourdakis Feb 25 '20 at 21:26
  • What exactly do you want to achieve there? `Foo::print` requires an object to be called on, because it is not static. With `foo.*foo_print` you still would only get that member function, but not bound to an object. – t.niese Feb 25 '20 at 21:26
  • @t.niese intuitively, I tought the "foo." of "foo.*foot_print" could be the part binding the function. – Vince Feb 25 '20 at 21:32
  • @Vince if that would be the case `std::bind` would not require `foo` as a separate parameter – Slava Feb 25 '20 at 21:33
  • @Slava you may note that pointers to members applied to non-function members do "bind" using the proposed syntax, e.g. "int Foo::* pointer = &Foo::_value; std::cout << foo.*pointer << std::endl; " does print the value of the instance foo. – Vince Feb 25 '20 at 21:37
  • @Vince so how it changed what I said before? C++ does not support such "binding" so you cannot use it this way. Otherwise you could pass it to `std::bind` this way. – Slava Feb 25 '20 at 21:45
  • 1
    A non-static member variable will have a unique address for every instance of the class. The member functions will not (necessarily/conceptually). Think of a member function having one address only no matter how many instances of the class you create. – Ted Lyngmo Feb 25 '20 at 21:46

1 Answers1

3

You can't pass a non-static member function to execute, because it depends on the this element (and so it needs an invocation object), instead you can use a lambda:

execute([&](){foo.print();});
Alberto Sinigaglia
  • 12,097
  • 2
  • 20
  • 48