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

consteval函数可接收空类对象吗?多编译器编译分歧谁正确?

C++即时函数参数的编译器行为分歧

以下是测试代码:

struct Foo {
    consteval auto operator+(Foo) const noexcept {
        return Foo{};
    }
};

struct Bar : Foo {};

Foo func() {
    Bar foo, bar;
    return foo + bar;
}

上述代码中Foo是空类,可通过GCC和Clang编译,但无法通过MSVC编译。MSVC提示bar不是常量表达式,不能作为即时函数operator+的参数,而GCC和Clang无此报错。请问哪款编译器的处理符合C++标准?


结论:GCC与Clang的处理符合C++标准

根据C++标准,调用consteval函数时,实参必须是常量表达式。这里的关键在于:Bar类型的对象foo和bar在传递给operator+(参数类型为Foo)时,会触发隐式的复制初始化转换。对于空类Foo来说,这种转换是完全平凡的——没有任何需要运行时计算的操作,转换后的结果属于常量表达式范畴。

MSVC的错误在于误判了这种隐式转换的性质,错误地认为Bar对象无法转换为符合要求的常量表达式实参。而GCC和Clang正确识别了该平凡转换满足常量表达式的要求,因此编译行为符合C++标准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 17:16:27