Jul*_*ner 9 c++ templates vector std c++11
我有以下模板.
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;
}
Run Code Online (Sandbox Code Playgroud)
当我在我的代码中使用它时,我指定了模板参数.为什么编译器无法为我推断出这个?如何更改模板定义以使其工作?
vector<int> numbers = { 1, 3, 5 };
// vector<string> strings = map(numbers, [] (int x) { return string(x,'X'); });
vector<string> strings = map<int, string>(numbers, [] (int x) { return string(x,'X'); });
Run Code Online (Sandbox Code Playgroud)
可运行代码:http://ideone.com/FjGnxd
这个问题中的原始代码来自:std :: transform-like函数返回转换后的容器
Pra*_*ian 18
你的函数需要一个std::function参数,但你用一个lambda表达式来调用它.两者不是同一类型.lambda可转换为std::function,但模板参数推导需要完全匹配,并且不考虑用户定义的转换.因此扣除失败.
如果你真的传递std::function给deeduction确实有效map().
std::function<string(int const&)> fn = [] (int x) { return string(x,'X'); };
vector<string> strings = map(numbers, fn);
Run Code Online (Sandbox Code Playgroud)
避免必须指定模板参数的一种可能的解决方法是修改函数以接受任何类型的可调用而不是std::function对象.
template<typename T, typename Func>
std::vector<typename std::result_of<Func(T)>::type>
map(const std::vector<T> &v, Func f) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
另一个版本的相同想法,使用decltype而declval不是result_of
template<typename T, typename Func>
std::vector<decltype(std::declval<Func>()(std::declval<T>()))>
map(const std::vector<T> &v, Func f) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
最后,使用尾随返回类型
template<typename T, typename Func>
auto map(const std::vector<T> &v, Func f)
-> std::vector<decltype(f(v[0]))> {
// ...
}
Run Code Online (Sandbox Code Playgroud)