std::expected
Определён в заголовочном файле <expected> | ||
|---|---|---|
template< class T, class E > class expected; | (1) | (начиная с C++23) |
template< class T, class E >
requires std::is_void_v<T>
class expected<T, E>;
| (2) | (начиная с C++23) |
Шаблон класса std::expected предоставляет способ представления одного из двух значений: ожидаемого значения типа T или неожиданного значения типа E. expected никогда не бывает без значения.
1) Основной шаблон. Содержит ожидаемое или неожиданное значение в собственном хранилище, которое вложено в объект
expected.
2) Частичная специализация для void. Представляет ожидаемое значение void или содержит неожиданное значение. Если она содержит неожиданное значение, оно вложено в объект
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<U> | std::expected<U,error_type> |
Поля данных
| Поле | Описание |
|---|---|
bool has_val | указывает, представляет ли объект expected в данный момент ожидаемое значение(поле объекта только для иллюстрации*) |
T val (только основной шаблон) | ожидаемое значение (вариативное поле объекта только для иллюстрации*) |
E unex | неожиданное значение (вариативное поле объекта только для иллюстрации*) |
Функции-члены
создаёт объект expected (открытая функция-член) |
|
уничтожает объект expected вместе с содержащимся в нём значением (открытая функция-член) |
|
| присваивает содержимое (открытая функция-член) |
|
Наблюдатели |
|
| обращается к ожидаемому значению (открытая функция-член) |
|
| проверяет, содержит ли объект ожидаемое значение (открытая функция-член) |
|
| возвращает ожидаемое значение (открытая функция-член) |
|
| возвращает неожиданное значение (открытая функция-член) |
|
| возвращает ожидаемое значение, если оно есть, а в противном случае — другое значение (открытая функция-член) |
|
| возвращает неожиданное значение, если оно есть, а в противном случае — другое значение (открытая функция-член) |
|
Монадические операции |
|
возвращает результат применения заданной функции к ожидаемому значению, если оно есть; в противном случае возвращает сам expected (открытая функция-член) |
|
возвращает expected с преобразованным ожидаемым значением, если оно есть; в противном случае возвращает сам expected (открытая функция-член) |
|
возвращает сам expected, если он содержит ожидаемое значение; в противном случае возвращает результат применения заданной функции к неожиданному значению (открытая функция-член) |
|
возвращает сам expected, если он содержит ожидаемое значение; в противном случае возвращает expected с преобразованным неожиданным значением (открытая функция-член) |
|
Модификаторы |
|
| создаёт ожидаемое значение на месте (открытая функция-член) |
|
| обменивает содержимое (открытая функция-член) |
|
Функции, не являющиеся членами
|
(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 << "value: " << *num << '\n';
// If num did not have a value, dereferencing num
// would cause an undefined behavior, and
// num.value() would throw std::bad_expected_access.
// num.value_or(123) uses specified default value 123.
else if (num.error() == parse_error::invalid_input)
std::cout << "error: invalid input\n";
else if (num.error() == parse_error::overflow)
std::cout << "error: overflow\n";
else
std::cout << "unexpected!\n"; // or invoke std::unreachable();
};
for (auto src : {"42", "42abc", "meow", "inf"})
process(src);
}
Вывод:
str: "42", value: 42 str: "42abc", value: 42 str: "meow", error: invalid input str: "inf", error: overflow
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| Отчёт об ошибке | Применяется к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| LWG 4141 | C++23 | требование к выделению памяти было неоднозначным | содержащийся объект должен быть вложен в объект expected |
Ссылки
- Стандарт C++23 (ISO/IEC 14882:2024):
- 22.8 Ожидаемые объекты [expected]
См. также
|
(C++17) | типобезопасное объединение с тегом (шаблон класса) |
|
(C++17) | обёртка, которая может содержать объект, а может и не содержать его (шаблон класса) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/utility/expected