问题
I was tinkering around with the std::mem_fn
and couldn't manage to bind it to data/functions of an member of a struct (one layer deeper).
I hope that the code shows the problem better than I can describe it, because I'm not familiar with the terminology.
#include <functional>
struct Int
{
Int(int _x = 0) : x(_x) {}
int GetInt() const { return x; }
int x;
};
struct IntWrapper
{
IntWrapper(int _x = 0) : test(_x) {}
int GetWrappedInt() const { return test.GetInt(); }
Int test;
};
int main()
{
IntWrapper wrapper{ 123 };
auto x = std::mem_fn(&IntWrapper::GetWrappedInt);
//auto y = std::mem_fn(&IntWrapper::test.GetInt); // ERROR
//auto z = std::mem_fn(&IntWrapper::test.x); // ERROR
int a = x(wrapper);
//int b = y(wrapper);
//int c = z(wrapper);
//std::cin.ignore();
return 0;
}
The error message is the following:
error C2228: left of '.GetInt' must have class/struct/union
error C2672: 'std::mem_fn': no matching overloaded function found
error C3536: 'y': cannot be used before it is initialized
error C2064: term does not evaluate to a function taking 1 arguments
Question:
Is it possible to make these binds? Do I need std::bind
for this?
回答1:
According to the specification, std::mem_fn() takes as argument a member function pointer, i.e.
auto y = std::mem_fn(&Int::GetInt);
auto b = y(wrapper.test);
As far as I'm aware, std::mem_fn()
is more or less obsolete, since lambda expressions. For example
auto y = [](IntWrapper const&wrapper) { return wrapper.test.GetInt(); };
auto b = y(wrapper); // note: no need to get hold of member 'test'
回答2:
Since anyway the return type of std::mem_fn
is unspecified, I simply see no reason why using it instead of some lambda function:
auto x = [&wrapper]{ return wrapper.GetWrappedInt(); };
int a = x();
Or:
auto x = [](const IntWrapper& wrapper){ return wrapper.GetWrappedInt(); };
int a = x(wrapper);
I even think these are better since the compiler can have better optimization opportunities.
回答3:
Your syntax is wrong, &IntWrapper::test
is a pointer to member.
I've never seen &IntWrapper::test.GetInt
, I don't even know how it is getting parsed.
Perhaps this is what you want
auto y = std::mem_fn(&decltype(IntWrapper::test)::GetInt);
auto b = y(wrapper.test);
来源:https://stackoverflow.com/questions/44625665/mem-fn-to-function-of-member-object