c – 编译器不推导出模板参数(map std :: vector – > std :: vector)

前端之家收集整理的这篇文章主要介绍了c – 编译器不推导出模板参数(map std :: vector – > std :: vector)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下模板
template<typename T,typename U>
std::vector<U> map(const std::vector<T> &v,std::function<U(const T&)> f) {
    std::vector<U> res;
    res.reserve(v.size());
    std::transform(std::begin(v),std::end(v),std::end(res),f);
    return res;
}

当我在我的代码中使用它,我有指定模板参数.为什么编译器不能为我推断这个?如何更改我的模板定义以使其工作?

vector<int> numbers = { 1,3,5 };

// vector<string> strings = map(numbers,[] (int x) { return string(x,'X'); });

vector<string> strings = map<int,string>(numbers,'X'); });

可运行代码http://ideone.com/FjGnxd

这个问题的原始代码来自于:The std::transform-like function that returns transformed container

解决方法

你的函数需要一个std :: function参数,但是你用lambda表达式来调用它.两者不一样.一个lambda可以转换成std :: function,但是模板参数的扣除需要精确的匹配,不考虑用户定义的转换.因此扣除失败.

如果您实际将std ::函数传递给map(),则扣除工作正常.

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

Live demo

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

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

同一个想法的另一个版本,使用decltype和declare而不是result_of

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

最后,使用尾随返回类型

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

Live demo

原文链接:https://www.f2er.com/c/114852.html

猜你在找的C&C++相关文章