Структурированное связывание на const - PullRequest
11 голосов
/ 25 марта 2019

Должен ли компилироваться следующий код?

#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 говорит «да!».
  • GCC говорит "о нет, мужик!".
  • Clang говорит: «Ни за что!».

Итак, это MSVC ошибка?

Стандарт здесь не прост (я быстро посмотрел), но, учитывая правила для auto, я полагаю, a и b следует скопировать, отбрасывая cv-qualifier .

Ответы [ 2 ]

14 голосов
/ 25 марта 2019

Должен ли компилироваться следующий код?

Это не так.Это ошибка MSVC.

Декларация структурированной привязки вводит новое имя (только для спецификации), e, которое объявляется как:

auto e = x;

Тип e называется E, и поскольку инициализатор подобен кортежу, типы привязок задаются как tuple_element_t<i, E>.В этом случае E равно pair<int, int>, поэтому два типа просто int.Правило для decltype структурированной привязки - указывать ссылочный тип , поэтому decltype(a) и decltype(b) равны int.

Важной частью здесь является то, что a и b (структурированные привязки) происходят из изобретенной переменной (e), а не - ее инициализатор (x),e не const, потому что вы только что объявили auto.Мы копируем x, а затем привязываемся к этой (не const) копии.

8 голосов
/ 25 марта 2019

Статические утверждения в вашем коде должны потерпеть неудачу.Зачем?Потому что ваш код в основном такой же, как и в случае:

#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)>);
}

, который действительно не работает и на MSVC .

В C ++ типы выраженийзатухание при назначении : auto видит int, а не const int.Структурированное связывание просто позволяет вам делать больше, чем одно auto связывание за один раз.

... и поэтому тот факт, что MSVC не дает сбой в утверждениях в вашем коде, кажется ошибкой.

...