C++模板显式实例化触发C4667编译器警告的原因是什么?
C4667警告问题原因及修复方案
警告触发原因
- 显式实例化指令顺序错误:你在
vector2.cpp中先编写了运算符的显式实例化语句,后编写了运算符模板的具体实现代码。C++语法要求,显式实例化一个模板时,编译器必须在该实例化语句之前已经看到模板的完整定义,否则就会抛出C4667警告,提示找不到匹配的函数模板完成强制实例化。 - 功能正常的原因:编译到当前编译单元后半段时,编译器会看到运算符模板的实现代码,最终生成静态库时仍然能正确导出对应实例化的符号,因此你在其他项目链接该库时不会报错,功能可以正常运行,仅编译阶段会因为顺序问题抛出警告。
修复方案
调整vector2.cpp中所有模板的实现和显式实例化的顺序,把模板实现放到显式实例化语句之前即可,修改后的代码参考如下:
#include "vector2.h" namespace lib2d { // 先写Vector2模板的成员函数实现 template<typename T> Vector2<T>::Vector2(): x{ 0 }, y{ 0 } { } template<typename T> Vector2<T>::Vector2(const T& X, const T& Y): x{ X }, y{ Y } { } // 再写Vector2结构体的显式实例化 template struct Vector2<float>; template struct Vector2<int>; } // 先写+=运算符模板实现 template<typename T> lib2d::Vector2<T>& operator +=(lib2d::Vector2<T>& left, const lib2d::Vector2<T>& right) { left.x += right.x; left.y += right.y; return left; } // 再写+=运算符的显式实例化 template lib2d::Vector2<float>& operator +=(lib2d::Vector2<float>&, const lib2d::Vector2<float>&); template lib2d::Vector2<int>& operator +=(lib2d::Vector2<int>&, const lib2d::Vector2<int>&); // 先写-=运算符模板实现 template<typename T> lib2d::Vector2<T>& operator -=(lib2d::Vector2<T>& left, const lib2d::Vector2<T>& right) { left.x -= right.x; left.y -= right.y; return left; } // 再写-=运算符的显式实例化 template lib2d::Vector2<float>& operator -=(lib2d::Vector2<float>&, const lib2d::Vector2<float>&); template lib2d::Vector2<int>& operator -=(lib2d::Vector2<int>&, const lib2d::Vector2<int>&);
其余未列出的运算符重载也按照同样逻辑调整顺序,即可消除所有C4667警告。
内容的提问来源于stack exchange,提问作者JensB
相关产品推荐
相关产品推荐

