C++11含函数回调的多模板参数声明及MSVC2015推导失败问题
解决MSVC 2015无法自动推导模板参数的问题
这个问题在MSVC 2015里挺常见的,核心原因是旧版编译器对std::function的模板推导支持有局限。你的lambda是一个匿名闭包类型,并非std::function本身,当编译器试图推导execInParallel的T和R时,它没办法从lambda隐式转换为std::function<R(T&)>的过程中反向推导出模板参数,所以报错了。
下面给你两种可行的解决方案:
方案1:显式指定模板参数
最简单直接的方式,调用函数时手动告诉编译器T和R的类型,绕过自动推导的问题:
vector<int> tasks,res; // 显式指定模板参数<int, int> execInParallel<int, int>(tasks,res, [&](int&t) { int r = 0; return r; }, 2);
方案2:修改函数模板,避免依赖std::function推导
更优雅的方式是调整函数模板的定义,直接把可调用对象作为模板参数,让编译器通过可调用对象的类型来推导T和返回类型:
#include <type_traits> // 需要包含这个头文件来用std::invoke_result template <typename T, typename F> void execInParallel(vector<T>& tasks, vector<typename std::invoke_result<F, T&>::type>& res, F fn, int cores) { // 你的并行执行逻辑 // 比如:res.resize(tasks.size()); // 然后用多线程拆分tasks,调用fn处理每个元素并赋值到res }
调用的时候就可以像你原来那样写,不需要显式指定模板参数了:
vector<int> tasks,res; execInParallel(tasks,res, [&](int&t) { int r = 0; return r; }, 2);
如果你的MSVC 2015对std::invoke_result支持不好,可以换成C++11的std::result_of:
vector<typename std::result_of<F(T&)>::type>& res
这种方式的优势是让模板推导更灵活,不仅支持lambda,还能兼容函数指针、仿函数等各种可调用对象,同时避开了std::function带来的推导障碍。
内容的提问来源于stack exchange,提问作者Stepan Yakovenko
相关产品推荐
相关产品推荐

