如何在C++模板类中定义类自身类型的带约束静态模板变量
修正方案
首先你原有代码里ZERO、UNIT的外部定义加了static是错误的:类静态成员的外部定义不能加static关键字,否则会导致每个编译单元生成独立副本,触发链接错误。
1. 调整类内UNIT_M的约束
把类内的UNIT_M声明修改为增加m != 0的校验:
// 类内声明,C++11及以上兼容写法 template<unsigned int m, bool = (m <= n && m != 0)> static const Vector UNIT_M;
如果用C++20可以用更清晰的requires约束:
// 类内声明,C++20写法 template<unsigned int m> requires (m <= n && m != 0) static const Vector UNIT_M;
另外建议你修正第二个构造函数的未初始化问题:你现在的Vector(int index, F val)只给指定索引赋值,其余分量都是未初始化的垃圾值,改完才能保证单位向量的正确性:
Vector(int index, F val) { components = ::new F[n](); // 加括号值初始化所有分量为0 components[index] = val; }
2. 外部定义所有静态成员
// 外部定义ZERO,去掉static关键字 template<unsigned int n, class F> const Vector<n, F, true> Vector<n, F, true>::ZERO{0.0}; // 外部定义UNIT,去掉static关键字 template<unsigned int n, class F> const Vector<n, F, true> Vector<n, F, true>::UNIT{1.0}; // 外部定义UNIT_M,C++11及以上兼容写法 template<unsigned int n, class F> template<unsigned int m, bool B> const Vector<n, F, true> Vector<n, F, true>::UNIT_M(m-1, 1.0);
如果你用C++20的requires约束,UNIT_M的外部定义写法如下:
// 外部定义UNIT_M,C++20 requires写法 template<unsigned int n, class F> template<unsigned int m> requires (m <= n && m != 0) const Vector<n, F, true> Vector<n, F, true>::UNIT_M(m-1, 1.0);
这里用m-1作为索引是因为通常单位向量的UNIT_M<1>对应第一个分量(数组索引0)为1,如果你期望m直接作为数组索引,去掉-1即可。
不符合m <=n && m !=0的m值会因为模板参数匹配失败无法实例化,符合你的约束要求。
内容的提问来源于stack exchange,提问作者seanlego23
相关产品推荐
相关产品推荐

