2016-05-05 112 views
2

使用std::cref時遇到此問題。一個最小的例子是這樣的:實例化重載函數模板

template<typename Fn, typename T> 
auto apply(Fn f, const T &t) -> decltype(f(t)) 
{ 
    return f(t); 
} 

int n = 123; 
apply(std::cref<int>, n); // <- compile error: can't infer type `Fn` 
apply([](const int &x) { return std::cref(x); }, n); // ok 

我認爲與第一例子的問題是,std::cref<T>有兩個重載版本,一個接受const T &和其他接受std::reference_wrapper<const T>。是否有可能在我的情況下實例化一個特定的版本?

+1

'申請(的static_cast <性病::的reference_wrapper (*)(const int的&)>(標準:: CREF ),N);',但什麼是錯的拉姆達? –

+0

@PiotrSkotnicki我試圖做一些像'fmap(std :: cref,foos)'將'std :: vector '變換成'std :: vector >',而沒有lambda的語法看起來更乾淨。但這可能不可能! –

+0

你可以添加你自己的引用包裝函數並有'fmap(mycref,foos)' –

回答

1

問題是cref有幾種形式。所以,當你寫cref<int>目前尚不清楚哪些以下的你的意思是:

reference_wrapper<const int> cref (const int& elem) 
reference_wrapper<const int> cref (reference_wrapper<int>& x) 

拉姆達版本沒有這種模棱兩可。順便說一句,這是一個好主意,讓習慣了;-)

現在,如果可讀性一個真正的問題,沒有什麼能阻止你這樣做:

auto take_ref = [](const int &x) { return std::cref(x); }; 
apply(take_ref, n); // compile fine 
2

apply功能似乎有點多餘在這種情況下。爲什麼不切斷中間人?

#include <vector> 
#include <algorithm> 
#include <iterator> 
#include <functional> 

int main() { 
    std::vector<int> v(10); 
    std::vector<std::reference_wrapper<const int>> v2; 
    std::transform(v.begin(), v.end(), std::back_inserter(v2), 
     static_cast<std::reference_wrapper<const int>(*)(const int&)>(&std::cref<int>)); 
} 
+0

'apply'函數可以簡化真正的代碼。在真實情況下,它實際上類似於'std :: transform'。 –