5 ms·
Would you ever really use that? That just shows how bad it is, IMO. Any time I want a sum type I want names, not hardcoded integers.
by mk12 11mo ago
Would you ever really use that? That just shows how bad it is, IMO. Any time I want a sum type I want names, not hardcoded integers.
- Maxatar 11mo agoI treat std::variant the same way I treat std::tuple, which is that I use them internally/privately and don't expose them as part of a public API. If I want to expose a std::variant publicly then I take the effort to emulate Rust, which I think everyone agrees has an incredibly useful and elegant enum type so it looks like this: int main() { auto s1 = ConnectionState::Disconnected(); auto s2 = ConnectionState::Connecting(3); auto s3 = ConnectionState::Connected("192.168.1.5", 8080); for (const auto& state : {s1, s2, s3}) { state.visit( [](Disconnected) { std::cout << "Disconnected\n"; }, [](int retries) { std::cout << "Connecting (" << retries << " retries)\n"; }, [](const IpAddress& ip) { std::cout << "Connected to " << ip.host << ":" << ip.port << "\n"; }); } } To implement that I currently do need to write out boilerplate like below, but with C++26 I will be able to use the upcoming reflection feature to automatically implement the bulk of this code by reflecting on the std::variant directly: class ConnectionState : private std::variant<std::monostate, int, IpAddress> { public: static auto Disconnected() { return ConnectionState(std::monostate{}); } static auto Connecting(int retries) { return ConnectionState(retries); } static auto Connected(std::string host, uint16_t port) { return ConnectionState(IpAddress{std::move(host), port}); } template <typename... Fs> decltype(auto) visit(Fs&&... fs) const { auto visitor = Overload{std::forward<Fs>(fs)...}; return std::visit(visitor, *this); } private: using std::variant<std::monostate, int, IpAddress>::variant; }; using Disconnected = std::monostate; ...
- loeg 11mo agoI wouldn't use it (in any language), but the claim was that it is impossible. It isn't.