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::variant a 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 argue std::optional<T> is clearer.
  • For “T or U or V or nothing” you can either:
    • Add std::monostate as another alternative in std::variant, or
    • Wrap a std::variant in std::optional.
  • 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::optional could have been defined as std::variant<T, monostate>; others think that confuses user intent versus implementation detail.

Relation to void, unit, and bottom types

  • Recurrent theme: C++’s void is a “weird” pseudo-type:
    • Not properly constructible or usable in templates.
    • Behaves partly like a unit type (all void functions “return something”) and partly like a special case.
  • std::monostate is seen as a proper unit type for generic code, unlike void.
  • Thread debates whether void is better modeled as a unit type, bottom type, or just a historical hack; no consensus.

Templates and metaprogramming

  • std::monostate is 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, or Void are 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.