C++模板类报错:模板实参数量错误(1个,应为2个)求助
模板计算器类的编译错误解决
问题描述
我用模板实现计算器类时,定义了两个模板参数T和T1,但希望只传递一个模板类型,编译时报错:
Wrong number of template arguments (1, should be 2)
29 9 D:\dev c++\projects\CT-22036_A2_Q1.cpp [Error] wrong number of template arguments (1, should be 2)
原代码如下:
#include<iostream> #include<typeinfo> #include<cmath> using namespace std; template <class T,class T1> class cal{ protected: T val; public: cal(T val){ this->val=val; cout<<"Data type is "<<typeid(val).name()<<endl; // cout<<val; } // template<class T1> cal(const cal<T>& a){ this->val=a.val; } void operator = (const cal<T1>& a){ this->val=a.val; cout<<"Value has been Assigned: "<<val<<endl; } }; int main(){ cal<int> x(10); cal<float> y; y=x; }
错误原因
你定义的cal是双模板参数的类模板,但实例化时只传了一个类型(比如cal<int>),编译器找不到匹配的单参数模板版本,因此报错。另外代码还存在两个隐含问题:
- 没有默认构造函数,
main里的cal<float> y;无法编译 - 赋值运算符和拷贝构造的模板参数逻辑混乱,不符合模板类的设计规范
解决方法
方案1:给第二个模板参数设置默认值
如果希望保留双参数模板,但大部分场景只传一个类型,可以给T1设置默认值为T,这样编译器会自动补全第二个参数:
#include<iostream> #include<typeinfo> #include<cmath> using namespace std; // 给T1设置默认值为T,支持单参数实例化 template <class T, class T1 = T> class cal{ protected: T val; public: // 补充默认构造函数,满足cal<float> y;的需求 cal() = default; cal(T val){ this->val=val; cout<<"Data type is "<<typeid(val).name()<<endl; } // 拷贝构造函数直接使用当前类的模板参数,无需单独指定T cal(const cal& a){ this->val=a.val; } // 将赋值运算符改为模板版本,支持任意类型的cal对象赋值 template <class U> cal& operator = (const cal<U>& a){ if(this != &a){ // 避免自赋值 this->val = static_cast<T>(a.val); // 显式类型转换更安全 cout<<"Value has been Assigned: "<<val<<endl; } return *this; // 符合赋值运算符的常规返回值要求 } }; int main(){ cal<int> x(10); cal<float> y; y=x; }
方案2:重构为单模板参数类+成员模板赋值运算符
如果T1只是为了支持不同类型的赋值操作,完全没必要把它作为类的模板参数,直接把赋值运算符做成成员模板即可,类本身只保留核心类型参数T:
#include<iostream> #include<typeinfo> #include<cmath> using namespace std; // 类仅保留一个核心类型参数T template <class T> class cal{ protected: T val; public: cal() = default; // 补充默认构造 cal(T val){ this->val=val; cout<<"Data type is "<<typeid(val).name()<<endl; } // 拷贝构造函数 cal(const cal& a){ this->val=a.val; } // 模板赋值运算符,兼容任意类型的cal对象 template <class U> cal& operator = (const cal<U>& a){ if(this != &a){ this->val = static_cast<T>(a.val); cout<<"Value has been Assigned: "<<val<<endl; } return *this; } }; int main(){ cal<int> x(10); cal<float> y; y=x; }
额外说明
- 必须补充默认构造函数,否则
main中的cal<float> y;会因为找不到构造方式报错 - 赋值运算符返回
cal&是C++的常规写法,支持链式赋值(比如y = x = z;) - 加上
static_cast<T>可以避免隐式转换带来的类型安全问题
内容的提问来源于stack exchange,提问作者Qartzai
相关产品推荐
相关产品推荐

