此代码在 GCC 和 Clang 中有效,但在 MSVC 上无效:
#include <concepts>
#include <utility>
struct S {};
const S&& f();
S g();
static_assert(std::same_as<decltype(false ? f() : g()), const S>);
https://godbolt.org/z/99rMPzecM
MSVC 认为
decltype(false ? f() : g())
是 const S&&
哪一个是正确的?为什么?
MSVC 是错误的,这是一个编译器错误。要确定正确的类型,请考虑 [expr.cond] 中确定条件运算符类型的规则。
在这种情况下,
f()
返回一个const S&&
,它将在任何分析之前变成x值。
将 S
转换为 const S&&
时,它不能是目标类型,因为根据 [expr.cond] p4.2:
仅当引用直接绑定时才能形成隐式转换序列。
另一个转换是从
f()
到 g()
,即到 S
类型的纯右值。这是可能的,并且 f()
可以进行左值到右值的转换,变成 S
。然后:
否则,如果可以形成恰好一个转换序列,则将该转换应用于所选操作数,并且在本子条款的其余部分中使用转换后的操作数代替原始操作数。
具体来说,对于子条款的其余部分,
f()
被转换为S
,并且? f() : g()
应该被视为两边都是S
类型,这也意味着条件表达式的类型作为整体是S
.