且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

编译器不推导出模板参数(映射 std::vector -> std::vector)

更新时间:2023-11-13 21:45:28

您的函数需要一个 std::function 参数,但您正在使用 lambda 表达式调用它.两者不是同一类型.lambda 可以转换std::function,但模板参数推导需要完全匹配,并且不考虑用户定义的转换.因此推演失败.

Your function expects an std::function argument, but you're calling it with a lambda expression instead. The two are not the same type. A lambda is convertible to std::function, but template argument deduction requires exact matches and user defined conversions are not considered. Hence the deduction failure.

如果您实际上将 std::function 传递给 map(),则推导确实有效.

Deduction does work if you actually pass an std::function to map().

std::function<string(int const&)> fn = [] (int x) { return string(x,'X'); };
vector<string> strings = map(numbers, fn);

现场演示

避免必须指定模板参数的一种可能解决方法是修改函数以接受任何类型的可调用对象,而不是 std::function 对象.

One possible workaround to avoid having to specify the template arguments is to modify the function to accept any kind of callable, rather than an std::function object.

template<typename T, typename Func>
std::vector<typename std::result_of<Func(T)>::type>
    map(const std::vector<T> &v, Func f) {
        // ...
    }

相同想法的另一个版本,使用 decltypedeclval 而不是 result_of

Another version of the same idea, using decltype and declval instead of result_of

template<typename T, typename Func>
std::vector<decltype(std::declval<Func>()(std::declval<T>()))>
    map(const std::vector<T> &v, Func f) {
        // ...
    }

最后,使用尾随返回类型

Finally, using a trailing return type

template<typename T, typename Func>
auto map(const std::vector<T> &v, Func f) 
  -> std::vector<decltype(f(v[0]))> {
        // ...
    }

现场演示