Search code examples
c++c++17structured-bindings

Structured binding on const


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)>);
}
  • MSVC says "yes!".
  • GCC says "oh no, man!".
  • Clang says "no way!".

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.


Solution

  • 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.