三元运算符 '?:' 在 4.9.0 之前的 GCC 版本中推断出不正确的类型? [关闭]

Posted

技术标签:

【中文标题】三元运算符 \'?:\' 在 4.9.0 之前的 GCC 版本中推断出不正确的类型? [关闭]【英文标题】:Ternary operator '?:' deduces incorrect type in GCC versions pre 4.9.0? [closed]三元运算符 '?:' 在 4.9.0 之前的 GCC 版本中推断出不正确的类型? [关闭] 【发布时间】:2017-07-28 17:15:57 【问题描述】:

以下代码演示了使用三元运算符的 GCC 问题(版本

static_assert(std::is_same<int, decltype(true ? std::declval<int>() : std::declval<int>())>::value,
              "Succeeds on GCC < 4.9.0");
static_assert(std::is_same<int&&, decltype(true ? std::declval<int>() : std::declval<int>())>::value, 
              "Succeeds on GCC >= 4.9.0");

第二行是正确的实现,因为 (true ? int&& : int&&) 应该推导出 int&& 而不是 int。

这可以通过Godbolt's compiler explorer进行演示

【问题讨论】:

哪个版本的 gcc? 没有人应该使用 GCC 4.anything for c++ 我没有看到你在declval&lt;int&gt;() 上做decltype,我看到你在? 的返回值上做这件事。为什么你声称的东西与你的代码所展示的不同,我很困惑。 即,您正在对static_assert(std::is_same&lt;int&amp;&amp;, decltype(std::declval&lt;int&gt;())&gt;::value, "what you asked") 提出声明,这与您问题中的代码完全不同。该代码是declval? 的混合体。你的问题是declval 还是??如果declval,请minimal reproducible example 并删除所有? 噪音。如果?,请询问? 而不是declval... 其实all versions of GCC with declval support说decltype(declval&lt;int&gt;())就是int&amp;&amp;。 VTC,因为声称的行为不可重现。 【参考方案1】:

通过Matt Godbolt's compiler explorer,GCC 似乎改变了在版本 4.9.0 之后触发哪个断言的想法。所以这似乎是一个不久前修复的错误。

注意declval() 是defined as

template<class T>
typename std::add_rvalue_reference<T>::type declval() noexcept;

所以我希望declval&lt;int&gt;() 的返回类型为int&amp;&amp;

【讨论】:

【参考方案2】:

这个bug在古版gcc中。

这个表达式是原因:

decltype(true ? std::declval<T>() : std::declval<U>());

std::declval&lt;T&gt;() 的正确结果是T&amp;&amp;

decltype(T&amp;&amp;)T&amp;&amp; 因为在这种情况下 T&& 是一个实体。

【讨论】:

所以要澄清的是 decltype(true ? std::declval() : std::declval()) 是 int 而不是 int&& 的 GCC 错误?这应该是推导出常见的类型。 在我看来是正确的

以上是关于三元运算符 '?:' 在 4.9.0 之前的 GCC 版本中推断出不正确的类型? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React JS 中使用三元运算符将 Font Awesome Icons 与文本一起使用?

三元运算和lambda

FizzBu​​zz 使用三元条件运算符

使用三元运算符或仅短路评估之间的区别?

如何使用三元运算符有条件地初始化 const char* arr[]

三元运算符