std::expected
Материал из cppreference.com
Определено в заголовочном файле <expected>
|
||
template< class T, class E > class expected; |
(начиная с C++23) | |
Шаблон класса std::expected
позволяет хранить одно из двух значений. Объект std::expected
в любой момент времени содержит либо ожидаемое значение типа T
, либо неожидаемое значение типа E
. std::expected
никогда не бывает без значения.
Сохранённое значение распределяется непосредственно в хранилище, занимаемом объектом expected
. Динамического выделения памяти не происходит.
Программа некорректна, если она создаёт экземпляр expected
со ссылочным типом, типом функции или специализацией std::unexpected. Кроме того, T
не должно быть std::in_place_t или std::unexpect_t.
Содержание |
[править] Параметры шаблона
T | — | тип ожидаемого значения. Тип должен быть либо (возможно, cv-квалифицированный) void, либо соответствовать требованиям Destructible (в частности, массивы и ссылочные типы не допускаются). |
E | — | тип неожидаемого значения. Тип должен соответствовать требованиям Destructible и должен быть допустимым аргументом шаблона для std::unexpected (в частности, массивы, необъектные типы и типы с cv-квалификацией не допускаются). |
[править] Типы элементы
Тип элемента | Определение |
value_type
|
T
|
error_type
|
E
|
unexpected_type
|
std::unexpected<E>
|
rebind
|
template< class U > using rebind = expected<U, error_type>; |
[править] Функции-элементы
создаёт объект expected (public функция-элемент) | |
уничтожает объект expected вместе с содержащимся в нём значением (public функция-элемент) | |
присваивает содержимое (public функция-элемент) | |
Наблюдение | |
обращается к ожидаемому значению (public функция-элемент) | |
проверяет, содержит ли объект ожидаемое значение (public функция-элемент) | |
возвращает ожидаемое значение (public функция-элемент) | |
возвращает неожидаемое значение (public функция-элемент) | |
возвращает ожидаемое значение, если оно присутствует, иначе другое значение (public функция-элемент) | |
Монадические операции | |
возвращает результат данной функции по ожидаемому значению, если оно существует; в противном случае возвращает сам expected (public функция-элемент) | |
возвращает expected , содержащий преобразованное ожидаемое значение, если оно существует; в противном случае возвращает сам expected (public функция-элемент) | |
возвращает само expected , если оно содержит ожидаемое значение; в противном случае возвращает результат данной функции для неожидаемого значения (public функция-элемент) | |
возвращает само expected , если оно содержит о��идаемое значение; в противном случае возвращает expected , содержащее преобразованное неожидаемое значение (public функция-элемент) | |
Модификаторы | |
создаёт ожидаемое значение на месте (public функция-элемент) | |
обменивает содержимое (public функция-элемент) |
[править] Функции, не являющиеся элементами
(C++23) |
сравнивает объекты expected (шаблон функции) |
(C++23) |
специализация алгоритма std::swap (функция) |
[править] Вспомогательные классы
(C++23) |
представлен как неожидаемое значение (шаблон класса) |
(C++23) |
исключение, указывающее проверенный доступ к expected , содержащему неожидаемое значение (шаблон класса) |
(C++23) |
тег создания на месте для неожидаемого значения в expected (класс) (константа) |
[править] Примечание
Типы с такой же функциональностью называются Result
в Rust и Either
в Haskell.
Макрос тест функциональности | Значение | Стандарт | Комментарий |
---|---|---|---|
__cpp_lib_expected |
202202L | (C++23) | шаблон класса std::expected и связанные с ним вспомогательные классы
|
202211L | (C++23) | Монадические функции для std::expected
|
[править] Пример
Запустить этот код
#include <cmath> #include <expected> #include <iomanip> #include <iostream> #include <string_view> enum class parse_error { invalid_input, overflow }; auto parse_number(std::string_view& str) -> std::expected<double, parse_error> { const char* begin = str.data(); char* end; double retval = std::strtod(begin, &end); if (begin == end) return std::unexpected(parse_error::invalid_input); else if (std::isinf(retval)) return std::unexpected(parse_error::overflow); str.remove_prefix(end - begin); return retval; } int main() { auto process = [](std::string_view str) { std::cout << "str: " << std::quoted(str) << ", "; if (const auto num = parse_number(str); num.has_value()) std::cout << "значение: " << *num << '\n'; // Если бы num не имел значения, разыменование num // ривело бы к неопределённому поведению, а // num.value() сгенерировала бы std::bad_expected_access. // num.value_or(123) использует указанное значение по умолчанию 123. else if (num.error() == parse_error::invalid_input) std::cout << "ошибка: неверный ввод\n"; else if (num.error() == parse_error::overflow) std::cout << "ошибка: переполнение\n"; else std::cout << "непредвиденный случай!\n"; // или invoke std::unreachable(); }; for (auto src: { "42", "42abc", "meow", "inf" }) process(src); }
Вывод:
str: "42", значение: 42 str: "42abc", значение: 42 str: "meow", ошибка: неверный ввод str: "inf", ошибка: переполнение
[править] Ссылки
- C++23 стандарт (ISO/IEC 14882:2023):
- 22.8 Объекты expected [expected]
[править] Смотрите также
(C++17) |
типобезопасное размеченное объединение (шаблон класса) |
(C++17) |
обёртка, которая может содержать или не содержать объект (шаблон класса) |