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