条件表达式在MSVC与GCC/Clang中类型不一致,孰是孰非?
三目运算符类型推导的标准符合性分析
以下代码可在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>);
分歧点在于:MSVC认为decltype(false ? f() : g())的类型是const S&&,而GCC/Clang认为是const S。
结论
GCC和Clang的处理符合C++标准,MSVC的判定不符合标准,原因如下:
明确分支表达式的属性
f()是返回右值引用的函数调用,表达式的值类别是xvalue(亡值),类型为const S&&g()是返回非引用类型的函数调用,表达式的值类别是prvalue(纯右值),类型为S
条件表达式的类型与值类别推导(依据C++标准《expr.cond》规则)
- 首先推导两个分支的公共兼容类型:
S可隐式转换为const S,而const S&&可以绑定到const S类型的临时对象,因此条件表达式的结果类型为const S。 - 由于条件表达式最终会将两个分支统一为临时对象形式返回,其值类别为prvalue(纯右值)。
- 首先推导两个分支的公共兼容类型:
decltype的推导规则
根据C++标准,对*prvalue(纯右值)*表达式使用decltype时,推导结果为表达式的基础类型(不带引用修饰),因此decltype(false ? f() : g())的结果是const S。
MSVC的错误在于错误地将条件表达式的结果判定为xvalue(亡值),进而导致decltype推导得到const S&&,违背了标准中的类型与值类别推导规则。
内容的提问来源于stack exchange,提问作者ValueError
相关产品推荐
相关产品推荐

