C++17: структурированные привязки, контейнеры и новые типы

1
12694
Добавить в избранное

C++17 – релиз, который расширил возможности C++: в языке появились структурированные привязки, контейнеры и новые типы данных.

Контейнеры и новые типы

В версии 17 в стандартной библиотеке C++ появилось много полезных типов данных. Простейший – std::byte. Это просто единичный байт, который предназначен для работы с хранилищем данных.

std::variant

Этот тип умеет в заданное время хранить в себе значение какого-то альтернативного типа. Представьте, что поле с количеством полных лет пользователя будет реализовано как строковая дата и целочисленное значение:

std::variant взаимодействует с объектами, которые не относятся к POD-типам. В этом его отличие и преимущество перед обычными объединениями.

std::optional

std::optional является объектом, который может как хранить значение, так и быть пустым. Он будет полезен в ситуации, когда функция не возвращает значение – тогда им может стать std::optional. Использование std::optional также снижает вероятность случайного использования пустого значения.

Здесь определяется функция, которая должна преобразовать строку в целое число. С использованием std::optional при неудаче вернется ноль.

std::any

Предоставляет типобезопасный контейнер для единственного значения любого типа. Можно проверить содержимое std::any и достать из него значение, использовав std::any_cast:

Также можно применить type() при проверке содержимого, чтобы не получить исключение.

std::any поможет там, где помогал указатель void*, только будет типобезопасным. Он позволит представить значение «5» и в виде целого, и в виде строки.

Структурированные привязки и множественное присваивание

Структурированные привязки – полезная новинка C++17. Они позволяют делать множественные привязки к структурированным типам, вроде массивов и кортежей. Это нужно, чтобы, например, присвоить все члены структуры независимым переменным единственным вызовом. Использование структурных привязок делает код в целом более чистым и понятным.

Кортежи

Эта структура появилась в C++11. Они аналогичны массивам и представляют собой коллекции с фиксированной длиной. Кортежи можно использовать, чтобы вернуть несколько значений функции, например так:

Этот пример вернет кортеж с двумя членами. В C++14 версии появилась возможность использовать auto с возвращаемыми типами функций, чтобы сделать вызов функции более аккуратным. Для получения значений кортежа, при этом, будет требоваться std::get:

Через std::tie можно привязать элементы кортежа к переменным, которые уже должны быть объявлены:

Благодаря этому методу можно привязывать элементы кортежа к переменным без std::get и необходимости объявлять переменные заранее:

Этот метод также позволяет получить ссылки к элементам кортежа, что невозможно с std::tie:

Массивы и структуры

Кроме кортежей, структурированные привязки можно применять к массивам и структурам:

То же с массивами:

Но в этих примерах есть недостатки:

  • Структурированные привязки не применяются к части элементов, только ко всем сразу. Это обусловлено ограничениями std::tie. Если какие-то элементы не нужно привязывать, можно использовать подготовленные для этого мусорные переменные, как в примере с массивом (_dummy1, _dummy2).
  • Деструктуризация будет работать только на один уровень вглубь.

К примеру, в Person имеется элемент Location:

Соберем Person и Location, используя вложенную инициализацию:

В заключение, все это работает только для классов с публичными и нестатичными данными. Основные компиляторы, вроде GCC, Clang и MSVC уже поддерживают нововведения. Подробности описаны на cppreference.

Интересуетесь программированием на C++?

Подпишитесь на нашу рассылку, чтобы получать больше интересных материалов:

И не беспокойтесь, мы тоже не любим спам. Отписаться можно в любое время.




Добавить комментарий