A "monostate" in the design-patterns lingo of 20 years ago was a class with only static member variables, basically where all state is shared state. It was supposed to be alternative to the Singleton pattern where you don't need all those .getInstance() calls and instead can just default-construct an instance, any instance, to get access to the shared state. It fell out of favor because usage was fairly error-prone and surprising to programmers who are not familiar with the pattern. Most people expect that when you create a new instance, you are actually creating new state, but monostate intentionally makes each new instance just a window on the shared global state.<p>I would've thought that the C++ template class would be just a marker interface to use on a monostate, so that users of the class <i>know</i> that it has shared state. But it seems like usage patterns in the article are very different from that, and all the comments here are ignorant of the history of the monostate pattern and befuddled at its intended usage. Maybe it was added to the standard by someone familiar with the design pattern, but they didn't do a good job with education and documentation to explain to everyone else what it was for?
What's really weird to me is not that C++ has a unit type and picked a weird name for it (that's just C++). The weird thing is how many unit types it has:<p>- std::nullopt_t<p>- std::nullptr_t<p>- std::monostate<p>- std::tuple<><p>And I'm sure there's more.
So it appears this follows the terrible C++ "naming things with the wrong name on purpose" trend, with the biggest example being naming a variable length array (a list, collection, etc) `std:vector` even though Vector was already a well known word with a very different meaning.<p>The word/type they wanted for this was the Unit type: <a href="https://en.wikipedia.org/wiki/Unit_type" rel="nofollow">https://en.wikipedia.org/wiki/Unit_type</a> and in that list it even states the `std:monotype` is a Unit.
Another use of std::monostate is as a special "unset/don't care" value for a template parameter. eg<p><pre><code> template<typename T = std::monostate>
class C
{
...
if constexpr (!std::is_same_v<T, std::monostate>
{
// T-related behaviour here
}
};</code></pre>
There's a fun thing like this in Swift too! `Void` is an empty tuple, and has all of the related constraints (can't conform to protocols, being the most salient one). If you have a type that has to conform to, say, `Equatable` or `Codable` you should instead use `Never?` which you can conform to most protocols via throwing `fatalError` on an extension of `Never` to the protocol.<p>Anyway, I write basically this on my blog for a more thorough explanation: <a href="https://www.jackyoustra.com/blog/non-equatable-void" rel="nofollow">https://www.jackyoustra.com/blog/non-equatable-void</a>
Good thing they made this instead of expanding the standard library to be more like Java's or Python's. It still only contains the most basic functions, and std::monostate ;)
Gerard: But it doesn't <i>do</i> anything!<p>Hans: No -- it <i>does</i> nothing.<p><a href="https://scryfall.com/card/wth/154/null-rod" rel="nofollow">https://scryfall.com/card/wth/154/null-rod</a>
It's poor name. If it has no members, it holds no bits. Therefore it has no state. It's not enough for an object to exist in order to hold state. It must be capable of distinguishing at least between two values, like true or false. If something doesn't hold state, the word <i>state</i> has no business in its name.<p>This thing is just a counterpart to <i>void</i> that is a class. A better name would be <i>voidclass</i> or something along those lines.<p>(There is a Monostate pattern, but that involves a class with state: just all the state is static. It's basically like a module with global variables. Completely different thing.)
Raymond is a very smart and productive person, and is not maligning C++ at all in this article. It makes me want to reassess my bittersweet perspective on the language.
So... Isn't the fact that you can't default-construct that variant without `monostate` working-as-intended?<p>Not everything can or should be default-constructed or default-constructible. That does complicate initialization sometimes (i.e. there are practical reasons to "suspend" construction until you have all the needed data), but you're not avoiding breaking type safety by adding a `monostate`, you're just giving yourself the "could be null" headache.
Seems almost intentionally confusingly written. Why not use void if monostate is like void? Ah, because monostate is actually entirely unlike void. void has zero values, mono state exactly one.