我的程序移植到 Visual Studio 后显示了一些奇怪的结果。简化后,我得到了这个最小的可重现示例:

consteval auto operator +( auto x, auto&& y ) {
    return x += y;
}

struct S {
    constexpr operator float() { return 1; }
};

int main() {
    return 0 + S{};
}

我希望它返回1,但在 Visual Studio 中它只返回一个任意数字3422303056,并且汇编代码表明该值是在不断求值期间计算的:

main    PROC
        mov     eax, 1610363728                     ; 5ffc3350H
        ret     0
main    ENDP

在线演示:

这个程序是不是有点不完善?

8

  • 1
    你可以包装进去static_assert真正看到 msvc 失败的


    – 

  • 2
    @DrewDormann:即使没有重新定义int+float,问题仍然存在


    – 


  • 2
    0.f + S{}运行


    – 

  • 1
    return x += 1.f;也失败了 – 现场 – – 我的投票是 MSVC 错误。


    – 

  • 2
    似乎consteval(或constexpr) 上的operator+是 MSVC 的错。删除它,它就会做正确的事情。它看起来像是在添加float位模式,就好像它是 – 的模式一样int,但它并不一致。


    – 



最佳答案
1

这里没有什么令人惊讶的 C++ 规则相关。

重载解析和常量表达式求值应该在这里按照预期的方式运行,并且程序应该返回1

似乎是 MSVC 的一个错误。

(从技术上讲,我认为float不需要能够1完全按照 C++ 标准表示。在这种情况下,结果可能会有所不同。但在使用 IEEE 754 浮点实现的情况下,情况并非如此。)