C++ const上的结构化绑定

C++ const上的结构化绑定,c++,c++17,structured-bindings,C++,C++17,Structured Bindings,下面的代码应该编译吗 #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)>); } #包括 void foo(){ 常数st

下面的代码应该编译吗

#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)>);
}
#包括
void foo(){
常数std::对x={1,2};
自动[a,b]=x;
静态断言(std::is_const_v);
静态断言(std::is_const_v);
}
  • 说“是的!”
  • 说“哦,不,伙计!”
  • 说“不行!”

那么,这是MSVC的bug吗

这里的标准并不简单(我快速看了一下),但是考虑到
auto
的规则,我想,
a
b
应该复制,丢弃cv限定符

下面的代码应该编译吗

#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错误

引入一个新名称(仅适用于规范),
e
,声明如下:

auto e = x;
e
的类型称为
e
,由于初始值设定项类似于元组,因此绑定的类型由给出。在本例中,
E
pair
,因此这两种类型只是
int
。结构化绑定的
decltype
的规则是给出属性,因此
decltype(a)
decltype(b)
都是
int


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

代码中的静态断言应该失败。为什么?因为您的代码与以下情况基本相同:

#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)>);
}
#包括
void foo(){
常数int x_1=1;
常数int x_2=2;
自动a=x_1;
自动b=x_2;
静态断言(std::is_const_v);
静态断言(std::is_const_v);
}
这也是

< > > C++中,赋值< /强>表达式类型衰减:<代码> Audio/Co> >见<代码> int <代码>,而不是<代码> const int < /C>。结构化绑定只允许您一次执行多个
自动
绑定

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