Daily bit(e) C++. std::monostate для std::variant

Добавлено 4 ноября 2026 в 07:31

Daily bit(e) C++ 166, представление пустого std::variant с помощью std::monostate.

Daily bit(e) C++

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

Это может создать проблемы, поскольку требует конструирования первого элемента, что бывает затратно; кроме того, этот элемент может вовсе не поддерживать конструирование по умолчанию.

Чтобы избежать подобных сложностей и получить семантически «пустой» std::variant, можно использовать специальный тип std::monostate в качестве первого аргумента шаблона std::variant.

#include <variant>

struct X 
{
    X(int v) : v_(v) {}
    int v_;
};

struct Y 
{
    Y(double v) : v_(v) {}
    double v_;
};

// X, Y не могут быть сконструированы по умолчанию
// std::variant<X,Y> a; не скомпилируется, не может быть создан по умолчанию

std::variant<X,Y> a = Y{20}; // OK
// a.index() == 1

std::variant<std::monostate,X,Y> b; // OK, семантически "пустой"
// b.index() == 0, std::holds_alternative<std::monostate>(b) == true


std::variant<int,double> c;
std::variant<int,double> d{0};
// c == d

// распознать пустое состояние:
std::variant<std::monostate,int,double> e;
std::variant<std::monostate,int,double> f{0};
// e != f

Пример на Compiler Explorer

Теги

C++ / CppDaily bit(e) C++Программирование