2017-06-19 99 views
1

的这是一个后续问题的mem_fn到的mem_fn构件

mem_fn to function of member object

这是当前的代码。

#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; 
} 

原来的问题是关于通过IntWrapper对象检索Int结构的x值。我用mem_fn此,因为它似乎没有的功能之间进行区分返回一个intint成员变量(在这些线所见:

 int m = maxElem(vec, &Int::GetInt); 
     int n = maxElem(vec, &Int::x); 

IntWrapper对象的解决方案是添加.test

auto y = std::mem_fn(&Int::GetInt); 
auto b = y(wrapper.test); 

呼叫。但是,在maxElem功能,我不能,如果有制定一个办法做到这一点。

我想知道该呼叫以这种方式使mem_fnIntWrapper对象直接变为int x变量(没有帮助函数并且假定所有成员都是公共的)。

 //int o = maxElem(vec, ???) // what if GetWrappedInt didn't exist? 

原来的做法是auto y = std::mem_fn(&IntWrapper::test.GetInt); // ERROR,这当然不能编译,而是给出了这个概念。

在此先感谢!

+2

为什么不使用lambda? – Jarod42

+0

Lambda是可行的;我只是想知道是否可以用'mem_fn'完成。 –

+1

在这种情况下的一个很好的规则:如果可能的话,更喜欢在'std :: function','std :: bind','std :: mem_fn'上使用lambda。 Lambdas更加灵活,并允许编译器更加自由地进行优化。 – Walter

回答

1

您不能使用std::mem_fn以不同于指向成员的指针(例如指向成员的指针)。所以,你必须使用它。在您的特定情况下,可以实现与

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); 

不过,我强烈建议你使用lambda表达式只要有可能。 std::mem_fn应被视为不赞成使用,因为AFAIK没有达到至少通过其他方式无法达到的目的,即lambda。

+0

好吧,好的。谢谢,学到了新的东西:) –