What's the point of std:monostate? You can't do anything with it
Purpose of std::monostate
- Provides a concrete “unit” value: a type with exactly one value, used where a real type is required but no data is stored.
- Main advertised use: give
std::varianta default-constructible alternative when none of its other types are default-constructible. - Enables having a “none/uninitialized” alternative that is just another variant arm rather than a separate wrapper concept.
std::variant vs std::optional
- For “
T or nothing”, many arguestd::optional<T>is clearer. - For “
T or U or V or nothing” you can either:- Add
std::monostateas another alternative instd::variant, or - Wrap a
std::variantinstd::optional.
- Add
- The first approach:
- Keeps “none” on equal footing with other alternatives.
- Often uses less space and avoids an extra level of indirection compared to
optional<variant<...>>.
- Some suggest
std::optionalcould have been defined asstd::variant<T, monostate>; others think that confuses user intent versus implementation detail.
Relation to void, unit, and bottom types
- Recurrent theme: C++’s
voidis a “weird” pseudo-type:- Not properly constructible or usable in templates.
- Behaves partly like a unit type (all
voidfunctions “return something”) and partly like a special case.
std::monostateis seen as a proper unit type for generic code, unlikevoid.- Thread debates whether
voidis better modeled as a unit type, bottom type, or just a historical hack; no consensus.
Templates and metaprogramming
std::monostateis useful as:- A sentinel template parameter value to mean “feature disabled/unset”.
- A stand-in member type (often with
[[no_unique_address]]) when conditionally eliding data.
- Some prefer custom “tag” types instead, to avoid accidental use.
Naming and conceptual confusion
- Several people dislike the name “monostate”:
- It suggests a stateful pattern (historical “Monostate” design pattern) rather than “no data”.
- Alternatives like
unit,none, orVoidare proposed but have their own ambiguity.
- Broader complaint: C++ often repurposes established terms (vector, functor, monostate) with different meanings.
Wider context: many kinds of “nothing”
- Discussion touches on multiple “nothing”/unit-like types in C++ (
nullopt_t,nullptr_t,monostate,std::tuple<>) and in other languages (null/undefined, unit/void/Nothing, etc.). - Some see this proliferation and the associated rules as emblematic of C++’s growing complexity; a few consider such constructs best avoided in everyday code.