Structured binding on const

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.


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.