Is the following code supposed to compile?
#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)>);
}
So, is this an MSVC bug?
The standard is not straightforward here (I had a quick look), but considering the rules for auto, I suppose, a and b should be copied discarding cv-qualifier.
Is the following code supposed to compile?
It is not. This is an MSVC bug.
A structured binding declaration introduces a new name (for specification only), e, that is declared like:
auto e = x;
The type of e is called E, and since the initializer is tuple-like, the types of the bindings are given by tuple_element_t<i, E>. In this case E is pair<int, int>, so the two types are just int. The rule for decltype of a structured binding is to give the referenced type, so decltype(a) and decltype(b) are both int.
The important part here is that a and b (the structured bindings) come from the invented variable (e), and not its initializer (x). e is not const because you just declared it auto. What we're doing is copying x, and then taking bindings into this (non-const) copy.
The static assertions in your code should fail. Why? Because your code is basically the same as the case of:
#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)>);
}
which does indeed fail on MSVC as well.
In C++, expression types decay on assignment: the auto sees an int, not a const int. Structured binding simply lets you do more than a single auto binding at a time.
... and so the fact that MSVC doesn't fail on the assertions in your code seems to be a bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With