2017-06-19 100 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

好吧,好的。謝謝,學到了新的東西:) –