实例化重载的功能模板

时间:2016-05-05 17:59:32

标签: c++ templates c++11

使用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>。是否可以在我的情况下实例化特定版本?

2 个答案:

答案 0 :(得分: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>));
}

答案 1 :(得分:1)

问题是cref有几种形式。所以当你写cref<int>时,目前还不清楚你的意思是:

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

lambda版本没有这种歧义。顺便说一下,习惯它是个好主意;-)

现在,如果可读性确实存在问题,那么没有什么可以阻止你这样做:

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