Reputation: 3567
i'm trying to understand a concept and an error. what's wrong with this?
class A
{
public:
A()
{
std::function<void(int)> testFunc(&A::func);
}
private:
void func(int) {}
}
my question, is it possible to create any sort of object that is able to call a member of a specific instance where std::function acts like a member function pointer, except without the wacky type definition that can't be used as function parameters in inheriting classes. for example:
class A
{
public:
A()
{
index[WM_CREATE] = &A::close;
index[WM_DESTROY] = &A::destroy;
}
protected:
map<UINT msg, void (A::*)(HWND, UINT , WPARAM, LPARAM)> index;
void close(HWND,UINT, WPARAM, LPARAM);
void destroy(HWND, UINT, WPARAM, LPARAM);
};
class B : public A
{
public:
B()
{
index[WM_CREATE] = &B::create; // error because it's not a pointer of type A::*
}
private:
void create(HWND, UINT, WPARAM, LPARAM);
};
I'm thinking i'm on the right track of using std::functions like so:
class A
{
public: // Gigantic stl error with these two
A() // |
{ // V
index[WM_CREATE] = std::function<void(HWND, UINT, WPARAM, LPARAM>(&A::close);
index[WM_DESTROY] = std::function<void(HWND, UINT, WPARAM, LPARAM>(&A::destroy);
}
protected:
map<UINT msg, std::function<void(HWND, UINT, WPARAM, LPARAM)> > index;
void close(HWND,UINT, WPARAM, LPARAM);
void destroy(HWND, UINT, WPARAM, LPARAM);
};
class B : public A
{
public: // and this one
B() // |
{ // V
index[WM_CREATE] = std::function<void(HWND, UINT, WPARAM, LPARAM)>(&B::create);
}
private:
void create(HWND, UINT, WPARAM, LPARAM);
};
if someone could explain what these giant cryptic errors mean and how to fix them, i would greatly appreciate it.
Upvotes: 18
Views: 14984
Reputation: 36409
With c++11 you can also use lambdas which are slightly easier to read than std::bind
:
index[WM_CREATE] = [this](HWND h, UINT u, WPARAM w, LPARAM l)
{
create(h, u, w, l);
}
Upvotes: 2
Reputation: 12975
I think the problem you are having is that a member function requires not only a function pointer, but a pointer to the calling object. In other words, member functions have an additional implicit argument that is the pointer to the calling object.
To set a member function to a std::function, you need to use std::bind like this:
std::function<void(int)> testFunc(std::bind(&A::func, this, _1));
This binds the this pointer of the current A instance to the function so it has the function pointer and the object instance, which is enough information to properly call the function. The _1 argument indicates that the first explicit argument will be provided when the function is called.
Upvotes: 20
Reputation: 35449
my question, is it possible to create any sort of object that is able to call a member of a specific instance
In this case the only information that is missing is in fact what specific instance the std::function
object should use: &A::func
can't be used on its own (for instance (this->*&A::func)(0)
uses &A::func
with instance *this
). Try:
std::function<void(int)> testFunc = std::bind(&A::func, this);
(Be careful that std::bind(&A::func, *this)
and std::bind(&A::func, this)
have slightly different semantics.)
Upvotes: 1