为何带执行策略与显式模板的std::copy无法编译?
std::copy显式指定模板参数编译失败的原因 可编译代码
#include <algorithm> #include <execution> class Test { Test() { double* a; std::copy<double*, double*>(a, a, a); std::copy(std::execution::seq, a, a, a); } };
不可编译代码
#include <algorithm> #include <execution> class Test { Test() { double* a; std::copy<std::execution::sequenced_policy, double*, double*>(std::execution::seq, a, a, a); } };
MSVC报错:
no instance of overloaded function 'std::copy' matches the argument list
argument types are (const std::execution::sequenced_policy, double *, double *, double *)
原因解析
问题核心是显式指定的模板参数与实参的类型不匹配:
带执行策略的
std::copy函数签名为:template<class ExecutionPolicy, class InputIt, class OutputIt> OutputIt copy(ExecutionPolicy&& policy, InputIt first, InputIt last, OutputIt d_first);其中第一个参数是转发引用(
ExecutionPolicy&&),会根据传入实参的类型自动推导ExecutionPolicy。std::execution::seq是全局的const对象,类型为const std::execution::sequenced_policy。当隐式调用(让编译器推导模板参数)时,ExecutionPolicy会被推导为const std::execution::sequenced_policy,此时转发引用会适配为const std::execution::sequenced_policy&&,可以正常绑定到std::execution::seq这个const左值,因此编译通过。当你显式指定第一个模板参数为
std::execution::sequenced_policy(非const)时,函数的第一个参数类型会变成std::execution::sequenced_policy&&(非const右值引用)。而std::execution::seq是const左值,无法绑定到非const的右值引用,导致编译器找不到匹配的重载,从而报错。
解决方法(如果非要显式指定模板参数)
将第一个模板参数指定为const std::execution::sequenced_policy,让参数类型匹配:
std::copy<const std::execution::sequenced_policy, double*, double*>(std::execution::seq, a, a, a);
内容的提问来源于stack exchange,提问作者rx303

