C++中不同浮点实例化模板类的赋值与类型转换问题
问题描述
我定义了一个基于浮点类型的模板类:
template <typename fl_t> class generic { fl_t a,b; /// 大量的getter和setter等方法... }
并将其分别实例化为double和float类型的别名:
typedef generic<double> dmatrix; typedef generic<float> fmatrix;
后续尝试将fmatrix对象赋值给dmatrix对象时,出现如下错误:
error: no viable conversion from 'const generic<float>' to 'generic<double>' note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'const fmatrix' (aka 'const generic<float>') to 'const generic<double> &' for 1st argument template <typename fl_t> class generic {
我编写了如下重载赋值运算符:
template <typename f> generic<f>& operator= ( const generic& g){ aSET(g.aGET(); // 其他属性同理 return *this; }
这段代码可以编译,但无法解决赋值问题。请问原因是什么?是否必须编写类型转换,其签名应该是什么?
问题分析与解决方案
你编写的赋值运算符存在两个关键问题:
- 模板参数不匹配:你定义的
operator=返回generic<f>&,但这个运算符是generic<fl_t>类的成员,模板参数f和类的模板参数fl_t没有关联,编译器无法推导出正确的类型匹配关系,无法触发该重载处理跨类型赋值。 - 参数类型限制:参数
const generic& g本质是const generic<fl_t>&,只能接收和当前类实例同类型的对象,根本无法容纳generic<float>这类其他模板实例化的对象。
要解决跨类型赋值问题,需要正确重载赋值运算符;若要支持dmatrix d = m;这类直接初始化场景,还需添加类型转换运算符。完整实现如下:
template <typename fl_t> class generic { public: fl_t a; double aGET() const {return double(a);} void aSET(double x) { a=fl_t(x);} // 跨类型赋值运算符:接收任意generic<f>类型对象 template <typename f> generic& operator=(const generic<f>& g){ aSET( g.aGET() ); return *this; } // 类型转换运算符:将当前generic<fl_t>转换为generic<f> template <typename f> operator generic<f>() { generic<f> m; m.aSET( aGET() ); return m; } }; typedef generic<double> dmatrix; typedef generic<float> fmatrix; // 测试示例 dmatrix fn(fmatrix m){ dmatrix d=m; // 使用类型转换运算符完成初始化 d=m; // 使用重载赋值运算符完成赋值 return d; }
核心说明
- 重载的
operator=返回generic&(即当前类的generic<fl_t>&),参数为const generic<f>&,可接收任意其他模板实例化的对象,实现跨类型赋值。 - 类型转换运算符
operator generic<f>()允许将当前类型对象隐式转换为generic<f>类型,支持直接初始化场景。
内容的提问来源于stack exchange,提问作者Kphysics
相关产品推荐
相关产品推荐

