Spec-Zone.ru › C++

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 вместе с содержащимся в нём значением
(открытая функция-член)
operator=
присваивает содержимое
(открытая функция-член)
Наблюдатели
operator->operator*
обращается к ожидаемому значению
(открытая функция-член)
operator boolhas_value
проверяет, содержит ли объект ожидаемое значение
(открытая функция-член)
value
возвращает ожидаемое значение
(открытая функция-член)
error
возвращает неожиданное значение
(открытая функция-член)
value_or
возвращает ожидаемое значение, если оно есть, а в противном случае — другое значение
(открытая функция-член)
error_or
возвращает неожиданное значение, если оно есть, а в противном случае — другое значение
(открытая функция-член)
Монадические операции
and_then
возвращает результат применения заданной функции к ожидаемому значению, если оно есть; в противном случае возвращает сам expected
(открытая функция-член)
transform
возвращает expected с преобразованным ожидаемым значением, если оно есть; в противном случае возвращает сам expected
(открытая функция-член)
or_else
возвращает сам expected, если он содержит ожидаемое значение; в противном случае возвращает результат применения заданной функции к неожиданному значению
(открытая функция-член)
transform_error
возвращает сам expected, если он содержит ожидаемое значение; в противном случае возвращает expected с преобразованным неожиданным значением
(открытая функция-член)
Модификаторы
emplace
создаёт ожидаемое значение на месте
(открытая функция-член)
swap
обменивает содержимое
(открытая функция-член)

Функции, не являющиеся членами

operator==
(C++23)
сравнивает объекты expected
(шаблон функции)
swap(std::expected)
(C++23)
специализирует алгоритм std::swap
(функция)

Вспомогательные классы

unexpected
(C++23)
представляет неожиданное значение
(шаблон класса)
bad_expected_access
(C++23)
исключение, указывающее на проверяемый доступ к expected, содержащему неожиданное значение
(шаблон класса)
unexpectunexpect_t
(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]

См. также

variant
(C++17)
типобезопасное объединение с тегом
(шаблон класса)
optional
(C++17)
обёртка, которая может содержать объект, а может и не содержать его
(шаблон класса)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/utility/expected

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API