C++17 Feature proposal: Allow std::monostate

71 views
Skip to first unread message

Will Cassella

unread,
Apr 25, 2022, 6:38:11 PM4/25/22
to cxx
std::monostate was introduced to the <variant> header in C++17 as an official "empty" type, the primary use case being if you have a `std::variant` consisting of types which are not default constructible, but you would like your variant to be default-constructible, then making `std::monostate` the first variant member would be a better alternative than using `std::optional<std::variant<...>>` or something similar.

As the implementation of std::monostate does not in any way depend on the implementation of std::variant, it could be useful for the same purpose with `absl::variant`, or in any other situation where you need a type with no state. I'm running into a use-case for this right now, where I'd like to use a hash-map-like container as a hash-set. By using `std::monostate` as the value type I can make my intentions clear without wasting too much space (though `std::monostate` is still uniquely addressable, so it will take up at least a byte + padding).

Alternatives could be to use `std::nullptr_t` (though that takes up more space, which is either surprising or unsurprising depending on how you think about it), create an `absl::monostate` implementation (though that might require adding abseil as a dependency to code that otherwise doesn't want that), or to create a bespoke "empty" type wherever this is needed.

I think the use-case for an "empty" type that isn't `void` appears often enough to make allowing this worthwhile.

Peter Kasting

unread,
Apr 25, 2022, 6:48:12 PM4/25/22
to Will Cassella, cxx
On Mon, Apr 25, 2022 at 3:38 PM Will Cassella <cas...@chromium.org> wrote:
As the implementation of std::monostate does not in any way depend on the implementation of std::variant, it could be useful for the same purpose with `absl::variant`, or in any other situation where you need a type with no state.

absl has absl::monostate, which is currently allowed (as part of absl/types/variant.h) and used in the codebase.

Whatever we do, I don't think we should also allow std::monostate alongside absl::monostate.

I'm running into a use-case for this right now, where I'd like to use a hash-map-like container as a hash-set. By using `std::monostate` as the value type I can make my intentions clear without wasting too much space (though `std::monostate` is still uniquely addressable, so it will take up at least a byte + padding).

Generally our map/set-like types expose both kinds of interfaces directly.  My inclination would be to make HashingLRUCache be similar?  That seems better than using any kind of empty type as the value type.

PK

Will Cassella

unread,
Apr 25, 2022, 7:04:52 PM4/25/22
to cxx, pkas...@google.com, cxx, Will Cassella
Sorry just realized after writing this that `absl::monostate` was already defined (a brief codesearch didn't reveal it, so I got excited a wrote this :)). Definitely agree that it wouldn't make sense for std::monostate and absl::monostate to coexist though. I'll see if I can apply the pattern used in `base::flat_tree` to make `base::LRUCache` more agnostic to whether it's being used as a map or a set.
Reply all
Reply to author
Forward
0 new messages