1

Continuing this thread I'd like to split it off into another more specific question. I want to bind a function using ChaiScript, and I can do that using std::function, but I can't seem to let std::function know which overload it should use.

Mirroring relevant methods:

class DLLExport Actor
{
public:
        Actor(Level* level, const String& name, Actor* parent);
        virtual ~Actor();

        void setPosition(const Real& x, const Real& y, const Real& z);
        void setPosition(const Vector3& position);
};

and then I'm trying to bind it like so:

std::function<void(Actor*, Vector3&)> setPos = &Actor::setPosition; // <-- C2440 here.
m->add(fun(setPos), "setPosition");

What I'm getting is the following error:

2>..\..\ScriptingDemo\Binder.cpp(63): error C2440: 'initializing' : cannot convert from 'overloaded-function' to 'std::function<void (Actor *, Vector3 &)>' 2> No constructor could take the source type, or constructor overload resolution was ambiguous

Community
  • 1
  • 1
Ilija Boshkov
  • 149
  • 2
  • 10
  • This boils down to http://stackoverflow.com/questions/4364599/c-overloaded-method-pointer – pmr Jan 18 '15 at 23:28

3 Answers3

2

Use a typedef to your member function :

typedef void (Actor::*set_type)(const Vector3&); // Note the syntax for a member function typedef

And use it for a clean static_cast to resolve the overload :

std::function<void(Actor&, const Vector3&)> setPos = static_cast<Actor::set_type>(&Actor::setPosition);

( note the implicit Actor& parameter to the member function, explicit in the above std::function<> signature)

quantdev
  • 23,517
  • 5
  • 55
  • 88
1

C++ overloaded method pointer.

Basically, put in the cast manually.

std::function<void(Actor*, const Vector3&)> setPos((void(Actor::*)(const Vector3&))&Actor::setPosition);

Now the why:

The = operator for std::function is (itself) a template and provides no type information for its argument. So when you try to assign it to &Actor::setPosition, there is no good way for the compiler to figure out which function you are asking for. Putting in the cast fixes that.

The Actor* argument comes from the type of function Actor::* rather than the function signature itself.

Community
  • 1
  • 1
IdeaHat
  • 7,641
  • 1
  • 22
  • 53
0

You're trying to convert a member function pointer to a free function pointer, and that can't work. Were that possible, you forgot the const in the std::function template arguments anyway.

Your inclusion of an Actor* is on the right track though :

#include <iostream>
#include <functional>

struct Foo {
    void bar(int const &i) { std::cout << i; }
};

int main()
{
    using namespace std::placeholders;
    std::function<void(Foo*, int const&)> func = std::bind(&Foo::bar, _1, _2);

    Foo foo;
    func(&foo, 17);

    return 0;
}

Note that you still need to provide an instance to call the method on at one point, but what would you expect ?

Quentin
  • 62,093
  • 7
  • 131
  • 191