Compiler does not deduce template parameters (map std::vector -gt; std::vector)(编译器不推导出模板参数(映射 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;
}
当我在代码中使用它时,我指定了模板参数.为什么编译器无法为我推断出这一点?我必须如何更改我的模板定义才能使其正常工作?
When I use it in my code I have the specify the template parameters. Why is the compiler not able to deduce this for me? How do I have to change my template definition to make this work?
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'); });
可运行代码:http://ideone.com/FjGnxd
这个问题的原始代码来自这里:标准::transform-like 函数,返回转换后的容器
The original code in this question comes from here: The std::transform-like function that returns transformed container
推荐答案
您的函数需要一个 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) {
// ...
}
相同想法的另一个版本,使用 decltype
和 declval
而不是 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]))> {
// ...
}
现场演示
这篇关于编译器不推导出模板参数(映射 std::vector -> std::vector)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:编译器不推导出模板参数(映射 std::vector -> std::vector)
基础教程推荐
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01