Почему структурированные привязки работают только с авто
Структурированные привязки были введены в C++17. Они дают возможность объявлять несколько переменных, инициализированных из кортежа или структуры.
Этот код компилируется с использованием c++17
компилятор.
#include <iostream>
#include <tuple>
int main() {
auto tuple = std::make_tuple(1.0, 1);
auto [ d, i ] = tuple;
std::cout << "d=" << d << " i=" << i << '\n';
return 0;
}
Если я не объявляю переменные с auto
Я получаю ошибку
ошибка: ожидаемое тело лямбда-выражения [d2, i2] = кортеж;
#include <iostream>
#include <tuple>
int main() {
auto tuple = std::make_tuple(1.0, 2);
double d2;
int i2;
[d2 , i2] = tuple;
return 0;
}
я использовал clang version 4.0.0
и вариант компиляции -std=c++1z
,
Могу ли я назначить существующие переменные структурированной привязке? Нужно ли использовать auto
?
2 ответа
Полученное вами сообщение об ошибке довольно показательно, почему оно разрешено только с auto
: отсутствие двусмысленности, которая сделает грамматику еще более зависимой от контекста.
Пара квадратных скобок в начале выражения указывает на лямбду. То, что вы спрашиваете, для стандарта, чтобы указать, что иногда [d2 , i2]
это начало лямбда, которая захватывает d2
а также i2
по значению, а в других случаях это распаковка. Все основано на том, что следует за этим.
Это просто не стоит сложности, чтобы добавить его к языку. Тем более, что, как заметил какой-то программист чувак, у вас уже есть std::tie
делать то, что вы хотите с кортежами.
Не только это, std::tie
позволяет игнорировать некоторые распакованные значения, а структурированные привязки пока не поддерживаются. Таким образом, все сводится к тому, чтобы иметь более ограниченную форму синтаксического сахара, чтобы делать то, что стандартная библиотека уже делает с кортежами.
Ох, и если вы недовольны, что std::tie
работает только с кортежами, вы можете расширить его для работы с любым POD самостоятельно. Просто посмотри на это magic_get
реализация. Можно применить ту же идею к constexpr
превратить POD в набор ссылок, который может быть передан std::tie
, Что-то вроде этого:
std::tie(d2, i2) = magic_unpack(/*some POD that isn't a tuple*/);
Также вы можете использовать std::tie()
распаковать кортеж на отдельные компоненты. Такие как
#include <iostream>
#include <tuple>
int main() {
auto tuple = std::make_tuple(1.0, 1);
double d2;
int i2;
std::tie(d2, i2) = tuple;
std::cout << "d2=" << d2 << " i2=" << i2 << '\n';
return 0;
}