4 ms·
std::variant comes pretty close, no?
by TwentyPosts 3y ago
std::variant comes pretty close, no?
- tialaramex 3y agostd::variant is a poor imitation. The C++ type system can't really do this, so it's contorted to try to get as close as we can, and the results aren't pretty. 1. Consider this Rust type: enum InvisibleDog { } - this is an Empty Type, there are no Invisible Dogs, Rust is OK with the existence of this type, although since it's uninhabited there can be no instances (and the type accordingly has no size, not zero size, no size at all). Such types don't make a whole lot of sense concretely, but they're crucial to good generic programming. In C++ we can't have such a type, the closest we can attempt is a std::variant whose only actual variant is valueless_by_exception and has a size of at least 1 byte. This is a disaster because it completely fails to achieve what we meant. 2. OK how about enum JustOneByte { Byte(u8) } - this type is as its name suggests, just a byte, Rust's u8 type. Its representation is accordingly one byte. But with std::variant we can't do that either, C++ has to account for valueless_by_exception and so it has to carry around a discriminator, so that it can discriminate between Byte, the only actual possible value of this type, and valueless_by_exception. As a result in C this type is larger than its "real" content, which is just one byte. 3. We can't do the guaranteed niche optimisation either. Rust's Option is literally just a sum type. It's not magic (in that sense, it's effectively a langitem so it is magic in some other ways). But despite the lack of magic Option<&T> is guaranteed to be the same size as &T is thanks to the guaranteed niche optimisation. C++ can't do that either.