You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否为局部类定义友元比较运算符?C++20编译器分歧解析

C++20局部类默认比较运算符的标准合规性问题

自C20起,编译器可为类生成默认比较运算符,包括以友元非成员函数的形式实现。针对局部类中使用该特性的两种写法,结合C标准分析如下:

第一种写法(仅MSVC支持)

代码示例:

void foo() {
    struct A;
    bool operator ==(const A&, const A&);
    struct A { 
        friend bool operator ==(const A&, const A&) = default;
    };
}

Clang和GCC均报错:

error: cannot define friend function 'operator==' in a local class definition

标准合规性分析:
根据C标准[class.friend]条款规定:只有非局部类的友元声明中才能定义函数,局部类不允许在友元声明里直接定义函数(包括使用=default的默认函数)。此处将operator==的默认定义写在局部类的友元声明中,属于在局部类内定义友元函数,违反了标准要求,因此这种写法不符合C标准,MSVC的支持属于非标准扩展。

第二种写法(仅GCC接受且有警告)

代码示例:

void foo() {
    struct A;
    bool operator ==(const A&, const A&);
    struct A { 
        friend bool operator ==(const A&, const A&);
    };
    bool operator ==(const A&, const A&) = default;
}

GCC给出警告:

warning: declaration of 'bool operator==(const foo()::A&, const foo()::A&)' has 'extern' and is initialized

MSVC和Clang直接拒绝编译。

标准合规性分析:
C标准明确禁止函数嵌套定义,即不能在一个函数内部定义另一个非成员函数。此处在foo()函数内定义全局作用域的operator==(即便其参数是局部类类型),本质上属于函数嵌套定义,违反了标准的核心规则,因此这种写法也不符合C标准。GCC的接受属于非标准行为,其警告也侧面反映了该写法的不合理性。

结论

上述两种写法均不符合C标准。当前C标准下,若需为局部类实现默认比较,建议直接将operator==声明为类的成员函数并使用=default,这种写法符合标准且能被所有主流编译器正确处理:

void foo() {
    struct A {
        bool operator==(const A&) const = default;
    };
}

内容的提问来源于stack exchange,提问作者Fedor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 16:46:16