下面的代码应该编译吗?
#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 错误吗?
这里的标准不是很简单(我快速浏览过),但是我认为考虑到auto
的规则,应该复制a
和b
丢弃 cv -qualifier 。
答案 0 :(得分:14)
下面的代码应该编译吗?
不是。这是一个MSVC错误。
A structured binding declaration引入了一个新名称(仅用于规范)e
,其声明如下:
auto e = x;
e
的类型称为E
,由于初始化程序类似于元组,因此绑定的类型由tuple_element_t<i, E>
给出。在这种情况下,E
是pair<int, int>
,所以这两种类型就是int
。结构化绑定的decltype
的规则是赋予referenced type,因此decltype(a)
和decltype(b)
均为int
。
这里的重要部分是a
和b
(结构化绑定)来自发明的变量(e
),而其初始化程序 not ( x
)。 e
不是const
,因为您刚刚声明了auto
。我们正在做的是复制x
,然后将绑定绑定到此(非const
)副本中。
答案 1 :(得分:8)
您的代码中的静态断言应该失败。为什么?因为您的代码与以下情况基本相同:
#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)>);
}
在C ++中,表达式类型在赋值时衰减:auto
看到int
,而不是const int
。结构化绑定仅使您一次可以执行多个auto
绑定。
...因此MSVC不会在代码中的断言上失败的事实似乎是一个错误。