Структурированное связывание на const - программирование
Подтвердить что ты не робот

Структурированное связывание на const

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

#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-квалификатор.

4b9b3361

Ответ 1

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

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

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

auto e = x;

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

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

Ответ 2

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

#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 не ошибается в утверждениях в вашем коде, кажется ошибкой.