Spec-Zone.ru › C++

std::expected

Определено в заголовке <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<U> expected<U, error_type>

Члены-функции

(конструктор)
конструктор объекта expected
(публичный член-функция)
(деструктор)
уничтожает объект expected вместе с содержащимся в нём значением
(публичный член-функция)
operator=
присваивание содержимого
(публичный член-функция)
Наблюдатели
operator->operator*
доступ к ожидаемому значению
(публичный член-функция)
operator boolhas_value
проверяет, содержит ли объект ожидаемое значение
(публичный член-функция)
value
возвращает ожидаемое значение
(публичный член-функция)
error
возвращает неожиданное значение
(публичный член-функция)
value_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++23 (ISO/IEC 14882:2023):
    • 22.8 Объекты expected [expected]

См. также

variant
(C++17)
тип-безопасный дизъюнктивный союз
(шаблон класса)
optional
(C++17)
оболочка, которая может или не может содержать объект
(шаблон класса)

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

Spec-Zone.ru

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