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

Объект 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
