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

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...