Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 333
BiagioF Avatar asked Mar 24 '19 23:03

BiagioF


2 Answers

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.

like image 121
Barry Avatar answered Oct 07 '22 10:10

Barry


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.

like image 24
einpoklum Avatar answered Oct 07 '22 11:10

einpoklum