【问题标题】:Structured binding on constconst 上的结构化绑定
【发布时间】:2019-03-24 23:44:12
【问题描述】:

下面的代码应该编译吗?

#include <type_traits>

void foo() {
  const std::pair<int, int> x = {1, 2};

  auto [a, b] = x;

  static_assert(std::is_const_v<decltype(a)>);
  static_assert(std::is_const_v<decltype(b)>);
}
  • MSVC 说“是的!”。
  • GCC 说“哦,不,伙计!”。
  • Clang 说“不可能!”。

那么,这是一个 MSVC 错误吗?

这里的标准并不简单(我快速浏览了一下),但考虑到 auto 的规则,我想,ab 应该被复制而丢弃 cv-qualifier .

【问题讨论】:

    标签: c++ c++17 structured-bindings


    【解决方案1】:

    下面的代码应该编译吗?

    事实并非如此。这是一个 MSVC 错误。

    A structured binding declaration 引入了一个新名称(仅用于规范)e,声明如下:

    auto e = x;
    

    e 的类型称为E,由于初始化器是类似元组的,绑定的类型由tuple_element_t&lt;i, E&gt; 给出。在这种情况下Epair&lt;int, int&gt;,所以这两种类型只是int。结构化绑定的decltype 的规则是给出referenced type,所以decltype(a)decltype(b) 都是int

    这里的重要部分是ab(结构化绑定)来自发明变量(e),而不是它的初始化器(x)。 e 不是 const,因为您刚刚声明了它 auto。我们正在做的是复制x,然后将绑定绑定到这个(非const)副本中。

    【讨论】:

      【解决方案2】:

      代码中的静态断言应该失败。为什么?因为你的代码和下面的情况基本一样:

      #include <type_traits>
      
      void foo() {
        const int x_1 = 1;
        const int x_2 = 2;
      
        auto a = x_1;
        auto b = x_2;
      
        static_assert(std::is_const_v<decltype(a)>);
        static_assert(std::is_const_v<decltype(b)>);
      }
      

      does indeed fail on MSVC 也是。

      在 C++ 中,表达式类型在赋值时衰减auto 看到的是 int,而不是 const int。结构化绑定只允许您一次执行多个 auto 绑定。

      ...因此,MSVC 不会在代码中的断言上失败这一事实似乎是一个错误。

      【讨论】:

        猜你喜欢
        • 2019-05-12
        • 1970-01-01
        • 1970-01-01
        • 2017-05-15
        • 2022-12-15
        • 2017-02-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多