boost::variant seems a powerful container to manipulate a heterogeneous set of types. I am wondering its cost. In memory, I think it takes up the size of the largest type plus an integer representing which(). For apply_visitor(), I think its performance is very good, it can call directly the function other than lots of ifs. Are my points right?
Boost. Variant provides a class called boost::variant that resembles union . You can store values of different types in a boost::variant variable. At any point only one value can be stored.
Its purpose is to demonstrate that std::variant can use one of the variant type's converting constructors as long as it is unambiguous. std::variant<std::string, int> x("abc"); instead, to show that off more clearly.
(since C++17) The class template std::variant represents a type-safe union. An instance of std::variant at any given time either holds a value of one of its alternative types, or in the case of error - no value (this state is hard to achieve, see valueless_by_exception).
You're almost right.
The size of boost::variant
is is the max size of any element, rounded up as needed for the largest alignment, plus the size of some integer, and again rounded up.
Think about a variant of these types, assuming the tag is uint32_t
:
struct foo { uint32_t value[3]; }; // size 12, align 4
struct bar { uint64_t v2; }; // size 8, align 8
An untagged union must have size 16, align 8; adding the 4-byte tag must go up to size 24 to keep align 8.
Or consider a variant of:
struct foo { uint8_t value[5]; }; // size 5, align 1
struct bar { uint16_t v2; }; // size 2, align 2
An untagged union of these must have size 6, align 2; adding the 4-byte tag forces you to size 12, align 4.
For calling, I expect it uses an array-of-functions lookup (that's how I implemented my own variant, which was necessary since boost's didn't support move constructors), since if chains don't perform well and switches are impossible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With