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,我想,a应该b复制丢弃cv-qualifier

4

2 回答 2

17

以下代码应该编译吗?

它不是。这是一个 MSVC 错误。

结构化绑定声明引入了一个新名称(仅用于规范),e其声明如下:

auto e = x;

的类型e被称为E,并且由于初始化器是类似元组的,绑定的类型由 给出tuple_element_t<i, E>。在这种情况下Epair<int, int>,所以这两种类型只是int。结构化绑定的规则decltype是给出引用的类型,sodecltype(a)decltype(b)are both int

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

于 2019-03-24T23:53:22.917 回答
9

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

#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)>);
}

确实在 MSVC 上也失败了

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

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

于 2019-03-24T23:53:47.403 回答