嵌套模板类场景下默认相等运算符在GCC中失效(外层类自定义==运算符、内层类使用默认==运算符)
嵌套模板类场景下默认相等运算符在GCC中失效(外层类自定义运算符、内层类使用默认运算符)
最近碰到个挺头疼的编译器差异问题,想跟大家唠唠:当我们写嵌套的模板类,外层类自己定义了==运算符,内层类用默认生成的==时,GCC会直接报错说找不到内层类的相等运算符,但Clang却能正常编译通过,这就很让人迷惑。
先看完整的代码示例:
template<typename T> struct Wrapper { T x; constexpr bool operator==(const Wrapper& other) const { return x == other.x; // 这里依赖T的operator== } }; template<typename T> struct Pair { T first; T second; constexpr bool operator==(const Pair& other) const = default; // 默认生成的相等运算符 }; int main() { Wrapper<Pair<int>> a, b; return a == b ? 0 : 1; }
问题表现
- 用Clang编译这段代码,完全没问题,能正常通过;
- 但用GCC编译时,会抛出类似
no match for 'operator==' (operand types are 'const Pair<int>' and 'const Pair<int>')的错误,仿佛Pair根本没有定义==运算符一样。
原因分析
这本质上是两个编译器对C++标准中默认成员函数的实例化时机理解不同导致的。Clang在处理Wrapper的operator==时,会正确识别到Pair的默认==运算符是隐式存在的,会触发它的生成;而GCC在这个场景下,可能没有及时触发Pair默认运算符的实例化,导致在查找x == other.x的运算符时,找不到对应的定义。
解决办法
如果你也遇到这个问题,可以试试这两个方案:
- 给Pair显式实现
==运算符,而不是依赖默认生成,比如把默认的那行改成手动比较:constexpr bool operator==(const Pair& other) const { return first == other.first && second == other.second; } - 或者在Wrapper的
operator==里,通过一些方式明确触发T的默认运算符生成,不过最直接的还是上面的显式实现方案。
备注:内容来源于stack exchange,提问作者j-tesla
相关产品推荐
相关产品推荐

