【问题标题】:decltype of ternary operator is different in MSVC ~C++17三元运算符的 decltype 在 MSVC ~C++17 中是不同的
【发布时间】:2021-09-18 07:34:42
【问题描述】:

std::common_referencedecltype 用于三元运算符?:

否则,如果 decltype(false? val<T1>() : val<T2>())(其中 val 是函数模板 template<class T> T val();)是有效类型,则成员类型类型命名该类型;

但是 MSVC 在下面的 C++20 代码中说 decltype(false? val<int&&>() : val<int&&>())int

#include <type_traits>

template<typename T>
T val();

int main() {
    static_assert(std::is_same<int&&, decltype(val<int&&>())>::value, "1");
    static_assert(std::is_same<int&&, decltype(false?val<int&&>():val<int&&>())>::value, "2");
}

https://godbolt.org/z/KE9PnGvd5

什么是正确行为?

这是一个 MSVC 缺陷吗?

【问题讨论】:

  • 行为应该是在这里返回一个右值引用。 cppreference 用“(4) If E2 and E3 are glvalues of the same type and the same value category, then the result has the same type and value category, and is a bit-field if at least one of E2 and E3 is a bit-field.”证实了这一点。 cppreference 当然不是一个规范的参考,但仍然是一个很好的健全性检查。 MSVC 可能会保留这种不良行为以防止破坏以前编译的代码。

标签: c++ visual-studio c++20


【解决方案1】:

这是一个 MSVC 错误。

条件运算符的规则在[expr.cond]中。这些规则中有很多部分非常复杂,但这种情况实际上很简单:

如果第二个和第三个操作数是相同值类别的glvalues并且具有相同类型,则结果是该类型和值类别,并且如果第二个或第三个操作数是位域,则结果是位域,或者如果两者都是位域。

这就是我们的例子:我们有两个int&amp;&amp;s,它们是相同值类别和相同类型的glvalues - 所以结果也是int&amp;&amp;

【讨论】:

  • @T.C.似乎应用标志不会影响 STL 并且可以安全使用。谢谢!
  • 所以这不是错误,而是默认情况下的不合规性,如@T.C.的链接到标志显示。简而言之,如果您想要一个更兼容的 C++ 编译器,而不是为向后兼容而设计的编译器,请使用 /permissive-
猜你喜欢
  • 2021-08-22
  • 2021-10-06
  • 2011-02-15
  • 2021-10-25
  • 2021-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多