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

默认飞船运算符<=>自定义返回类型:MSVC报错符合C++标准吗?

默认生成的operator<=>返回类型限制是否符合C++标准?

最新Visual Studio编译器仅允许默认生成的operator<=>返回std::strong_ordering、std::weak_ordering、std::partial_ordering这三种标准类型,这是否符合C++标准?以下通过两个示例分析:

示例1:返回void的默认operator<=>

代码实现:

struct A {
    void operator<=>(const A &) const = default;
};

编译器表现:GCC和Clang可正常编译,但MSVC报错误C7634:'void': is not a valid comparison type; consider using 'std::strong_ordering' instead。

合法性分析

根据C20标准,默认生成的比较运算符返回类型必须是auto、bool(仅适用于operator==)或比较类别类型(即std::strong_ordering、std::weak_ordering、std::partial_ordering)。void不属于上述合法类型,因此示例1的代码不符合C标准。MSVC的报错符合标准要求,而GCC和Clang的编译通过属于未严格执行标准检查的情况。

示例2:返回自定义比较类型的默认operator<=>

代码实现:

#include <compare>

struct A {
    int a;
    constexpr bool operator==(const A & r) const { return a == r.a; }
    constexpr int operator<=>(const A & r) const { return a - r.a; }
};

static_assert(A{1} <  A{2});
static_assert(A{3} >= A{2});

struct S : std::strong_ordering {
    constexpr S(std::strong_ordering b) : std::strong_ordering(b) {}
    constexpr S(int b) : std::strong_ordering(b <=> 0) {}
};

struct B : A {
    int b;
    S operator<=>(const B &) const = default;
};

static_assert(B{{1},2} <  B{{2},1});
static_assert(B{{1},1} <= B{{1},1});
static_assert(B{{3},2} >  B{{2},3});
static_assert(B{{2},2} == B{{2},2});

编译器表现:GCC和Clang可正常编译,MSVC报错误C2280并触发内部编译器崩溃。

合法性分析

C标准允许比较类别类型的派生类作为默认operator<=>的返回类型,因为派生类继承了基类的比较语义,属于合法的比较类别范畴。示例2中的S继承自std::strong_ordering,完全符合标准要求。MSVC的报错及内部崩溃属于编译器实现缺陷,不符合C标准的规定。

总结

  • 示例1代码不合法,MSVC的报错符合标准;
  • 示例2代码合法,MSVC的报错属于实现问题,不符合标准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 14:37:11