问题
This is a follow-up question to
mem_fn to function of member object
This is the current code.
#include <vector>
#include <algorithm>
#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;
};
template<class ContainerT, class Mem> constexpr auto maxElem(const ContainerT& _container, Mem _Pm)
{
auto memFn = std::mem_fn(_Pm);
return memFn(std::max_element(_container.cbegin(), _container.cend(), [&](auto _rhs, auto _lhs) { return memFn(_rhs) < memFn(_lhs); }));
}
int main()
{
{
std::vector<Int> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(i * 11 % 7); // some random values
}
int m = maxElem(vec, &Int::GetInt);
int n = maxElem(vec, &Int::x);
}
{
std::vector<IntWrapper> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(i * 7 % 11); // some random values
}
int m = maxElem(vec, &IntWrapper::GetWrappedInt);
//int o = maxElem(vec, ???) // what if GetWrappedInt didn't exist?
}
return 0;
}
The original question was about retrieving the x
value of the Int
struct through anIntWrapper
object. I used mem_fn
for this because it doesn't seem to distinguish between a function returning an int
and an int
member variable (Seen in these lines:
int m = maxElem(vec, &Int::GetInt);
int n = maxElem(vec, &Int::x);
The solution for IntWrapper
objects was to add .test
auto y = std::mem_fn(&Int::GetInt);
auto b = y(wrapper.test);
to the call. However, in the maxElem
function, I cannot do this.
I'm wondering if there is a way to formulate the call in such a way that the mem_fn
goes from the IntWrapper
object directly to the int x
variable (Without the helper function and assuming that all members are public).
//int o = maxElem(vec, ???) // what if GetWrappedInt didn't exist?
The original approach was auto y = std::mem_fn(&IntWrapper::test.GetInt); // ERROR
, which of course does not compile, but shows the idea.
Thanks in advance!
回答1:
You cannot use std::mem_fn
with something different than a pointer to member (such as a pointer to member of member). So, you must use that. In your particular case, you can achieve that with
std::vector<IntWrapper> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(i * 11 % 7); // some random values
}
auto m = maxElem(vec, &IntWrapper::GetWrappedInt);
However, I strongly advise you to use lambda expressions whenever possible. std::mem_fn
should be considered as if deprecated, since, AFAIK, it serves no purpose that cannot be achieved at least as well by other means, i.e. a lambda.
来源:https://stackoverflow.com/questions/44629067/mem-fn-to-mem-fn-of-member