实例化重载的函数模板

Instantiate overloaded function template

本文关键字:函数模板 重载 实例化      更新时间:2023-10-16

我在使用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>。在我的情况下,有可能实例化一个特定的版本吗?

在这种情况下,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>));
}

问题是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