可变参数模板静态构造函数报错:候选函数期望0参数,实际传入3个
问题描述
我尝试为scalar类编写一个静态可变参数模板构造函数,但由于缺乏可变参数模板经验遇到了错误。
编写的代码
template <typename T> struct scalar { template <typename... Args> static std::shared_ptr<scalar<T>> create(Args &&...args) { return std::make_shared<scalar<T>>((std::forward<Args>(args))...); } }; template <typename T> std::shared_ptr<scalar<T>> operator+(std::shared_ptr<scalar<T>> &lhs, std::shared_ptr<scalar<T>> &rhs) { auto res = scalar<T>::create(lhs->data + rhs->data, {lhs, rhs}, "+"); res->backward = [lhs, rhs, res]() { lhs->grad += res->grad; rhs->grad += res->grad; }; return res; }
错误信息
error: no matching function for call to ‘red_engine::scalar<double>::create(red_engine::scalar<double>::value_type, <brace-enclosed initializer list>, const char [2])’ 143 | auto res = scalar<T>::create(lhs->data * rhs->data, {lhs, rhs}, "*"); | ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/alex/projects/AI/nanograd/nanograd-cpp/engine.hpp:36:46: note: candidate: ‘static red_engine::scalar<T>::pointer red_engine::scalar<T>::create(Args&& ...) [with Args = {}; T = double; pointer = std::shared_ptr<red_engine::scalar<double> >]’ 36 | template <typename... Args> static pointer create(Args &&...args) { | ^~~~~~ /home/alex/projects/AI/nanograd/nanograd-cpp/engine.hpp:36:46: note: candidate expects 0 arguments, 3 provided
问题分析与解决
错误核心是编译器无法推导{lhs, rhs}这个花括号初始化列表的类型,可变参数模板的类型推导机制无法识别无明确类型的初始化列表,导致模板参数推导失败,编译器误以为create需要0个参数。
两种可行的修正方案:
方案一:显式指定初始化列表的容器类型
把{lhs, rhs}包装成明确的容器对象(比如std::vector),让编译器能推导出参数类型:auto res = scalar<T>::create( lhs->data + rhs->data, std::vector<std::shared_ptr<scalar<T>>>{lhs, rhs}, "+" );方案二:显式指定
create的模板参数
直接告诉编译器每个参数的类型,跳过自动推导:auto res = scalar<T>::create< typename scalar<T>::value_type, std::vector<std::shared_ptr<scalar<T>>>, const char* >(lhs->data + rhs->data, {lhs, rhs}, "+");
额外注意:需要确保scalar<T>的构造函数确实支持接收这三个类型的参数(数值、依赖节点容器、运算符字符串),如果构造函数签名不匹配,同样会导致调用失败。
内容的提问来源于stack exchange,提问作者ralex
相关产品推荐
相关产品推荐

