Страницы

Поиск по вопросам

понедельник, 8 октября 2018 г.

Новый синтаксис объявления переменных, получаемых из составного объекта

В c++17 появился новый синтаксис объявления переменных вида:
auto [x, y, z] = f();
где f() - функция, возвращающая составной объект (массив, кортеж, структуру и т.п.).
Как называется этот синтаксис и что он делает?


Ответ

Данная конструкция называется Structured binding declaration (Можно перевести как "объявление структурированной привязки") и позволяет объявлять сразу группу переменных (возможно даже разного типа) при наличии инициализирующего выражения. В качестве этого выражения в примере используется функция f
Рассмотрим несколько примеров использования:
#include #include #include #include
struct S { int i; std::string s; double d; };
S f() { return { 42, "hello", 1.5 }; }
std::map g() { return { { 1, "one" }, { 2, "two" }, { 3, "three" } }; }
int main() {
auto [i, s, d] = f(); std::cout << i << s << d << "
";
int a[] = { 5, 6, 7 }; auto& [x, y, z] = a; std::cout << x << y << z << "
"; x--; y++; z*=2; std::cout << a[0] << a[1] << a[2] << "
";
auto [ss, dd, ii] = std::make_tuple("ololo", 0.5, 100500); std::cout << ss << dd << ii << "
";
for (auto [k, v] : g()) { std::cout << "key=" << k << " value=" << v << "
"; } }
Результат выполнения:
42hello1.5 567 4714 ololo0.5100500 key=1 value=one key=2 value=two key=3 value=three
Можно видеть, что переменные i, s, d проинициализировались значениями соответствующих членов структуры S. Здесь стоит заметить, что важно не совпадение имён, а порядок членов.
При связывании переменных x, y, z с элементами массива a была использована ссылка &. Т.о. последующее изменение переменных затрагивает состояние элементов массива.
Переменные ss, dd, ii инициализированы элементами кортежа. Тут вроде бы всё просто.
Использование в цикле по диапазону позволяет сразу разбивать составной элемент (в данном случае std::pair) на компоненты. Аналогичный цикл в стиле c++11 мог бы выглядеть так:
for (auto e: g()) { std::cout << "key=" << e.first << " value=" << e.second << "
"; }
Т.о. данная конструкция упрощает написание кода при необходимости доступа к частям составного объекта.

Комментариев нет:

Отправить комментарий