条件表达式在 MSVC 和 GCC/Clang 之间产生不同的类型

问题描述 投票:0回答:1

此代码在 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&&

哪一个是正确的?为什么?

c++ gcc visual-c++ conditional-statements clang
1个回答
0
投票

MSVC 是错误的,这是一个编译器错误。要确定正确的类型,请考虑 [expr.cond] 中确定条件运算符类型的规则。

在这种情况下,

f()
返回一个
const S&&
,它将在任何分析之前变成x值。 将
S
转换为
const S&&
时,它不能是目标类型,因为根据 [expr.cond] p4.2:

仅当引用直接绑定时才能形成隐式转换序列。

另一个转换是从

f()
g()
,即到
S
类型的纯右值。这是可能的,并且
f()
可以进行左值到右值的转换,变成
S
。然后:

否则,如果可以形成恰好一个转换序列,则将该转换应用于所选操作数,并且在本子条款的其余部分中使用转换后的操作数代替原始操作数。

- [expr.cond] p4,第 7 句

具体来说,对于子条款的其余部分,

f()
被转换为
S
,并且
? f() : g()
应该被视为两边都是
S
类型,这也意味着条件表达式的类型作为整体是
S
.

© www.soinside.com 2019 - 2024. All rights reserved.