C++模板前置声明:如何为类添加operator==等友元运算符声明
关于MyBlob类友元运算符的模板前置声明问题
哥们,答案是肯定的——你确实需要先做这样的模板前置声明,主要原因有这两个:
- 解决依赖查找的坑:当你在
MyBlob类里把这些运算符声明为友元时,编译器得先知道这些是模板函数,不是普通的非模板函数。要是没前置声明,编译器会把友元声明当成非模板函数的声明,等你后面定义模板版的运算符时,就会出现匹配不上的错误,编译器会一脸懵:“你说的友元是那个非模板的,现在又整个模板的,这俩不是一个东西啊!” - 保证模板参数对齐:前置声明明明白白告诉编译器,这些运算符是和
MyBlob<T>用同一个模板参数T的函数,这样在类内部的友元声明里才能精准绑定到对应的模板实例,不会出现类型乱套的情况。
给你整个标准的正确代码结构参考:
// 先前置声明MyBlob模板类 template <typename T> class MyBlob; // 再前置声明各个模板运算符 template <typename T> bool operator==(const MyBlob<T> &, const MyBlob<T>&); template <typename T> bool operator!=(const MyBlob<T> &, const MyBlob<T>&); template <typename T> bool operator<(const MyBlob<T> &, const MyBlob<T>&); // 接着定义MyBlob模板类 template <typename T> class MyBlob { // 友元声明要加上<T>,明确绑定当前模板参数的运算符实例 friend bool operator==<T>(const MyBlob<T>&, const MyBlob<T>&); friend bool operator!=<T>(const MyBlob<T>&, const MyBlob<T>&); friend bool operator< <T>(const MyBlob<T>&, const MyBlob<T>&); // 空格是为了避免被解析成移位运算符 // 类的其他成员变量、函数... }; // 最后定义各个运算符的模板实现 template <typename T> bool operator==(const MyBlob<T>& lhs, const MyBlob<T>& rhs) { // 这里写你的比较逻辑,比如比较内部存储的元素 return true; } template <typename T> bool operator!=(const MyBlob<T>& lhs, const MyBlob<T>& rhs) { return !(lhs == rhs); // 直接复用==的逻辑就行,省得重复写 } template <typename T> bool operator<(const MyBlob<T>& lhs, const MyBlob<T>& rhs) { // 写你的小于比较逻辑,比如按元素顺序比较 return true; }
这里要特别注意:类内部的友元声明必须加上<T>,不然编译器会误以为你要声明一个新的非模板友元函数,到时候又会出一堆奇奇怪怪的错误。另外写operator< <T>时的空格是必要的,避免编译器把它当成移位运算符<<来解析。
当然,要是你把运算符的实现直接写在类内部(作为内联函数),那可能不用前置声明,但这种写法对于比较运算符来说一般不推荐,毕竟把所有逻辑都塞类里会让代码显得臃肿,还是分开写更清晰。
内容的提问来源于stack exchange,提问作者Sut
相关产品推荐
相关产品推荐

