#c #c 17 #structured-bindings
#c #c 17 #структурированные привязки
Вопрос:
Предполагается ли компиляция следующего кода?
#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?
Стандарт здесь не однозначен (я бегло просмотрел), но, учитывая правила для auto
, я полагаю, a
и b
следует скопировать, отбросив cv-qualifier.
Ответ №1:
Предполагается ли компиляция следующего кода?
Это не так. Это ошибка 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
) копию.
Ответ №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
, а не a const int
. Структурированная привязка просто позволяет выполнять больше, чем одну auto
привязку за раз.
… и поэтому тот факт, что MSVC не завершает работу с утверждениями в вашем коде, кажется ошибкой.