Given:
boost::variant<T1,T2,T3,...,TN>
Calculate the following at compile time:
max(sizeof(T1), sizeof(T2), sizeof(T3),... ,sizeof(TN))
I had no idea how to approach this, but this answer shed some light on how I might get started. Using the code in that answer with two types, T1
and T2
, I could use the following in a source file to get the size of the larger object:
size_t largestSize = sizeof(largest<T1, T2>::type);
This is exactly what I'd like to do, but I need the largest
template to work with more than two classes - specifically, it would need to check all types stored in a boost::variant
object.
I know that boost::variant
has a types
typedef, which defines some sort of list of types in the variant. The problem is, I get totally lost when I try to wrap my head around all the boost::mpl
stuff in the implementation. I don't intuitively understand what boost::variant::types
is, and how I might be able to pass it into my own template that does something with it.
In my head, this is what the final implementation might look like:
typedef boost::variant<T1, T2, T3, T4> MyVariant;
size_t largestSize = sizeof(largest<MyVariant::types>::type);
Unfortunately, I have no idea how to go about implementing this version of largest
.
I'm not sure if this is a reasonable approach, so I'm open to any other ways to accomplish this (maybe apply a boost::static_visitor
to all types at compile time?).
Just ignore the mpl stuff. Start with:
template <class T> struct max_variant_sizeof;
template <class... Ts>
struct max_variant_sizeof<boost::variant<Ts...>> {
static constexpr size_t value = variadic_max(sizeof(Ts)...);
};
Now max_variant_sizeof<MyVariant>::value
will forward all the sizes of all the types to a function. All you need to do is write that variadic_max
:
constexpr size_t variadic_max(size_t v) { return v; }
template <class... Args>
constexpr size_t variadic_max(size_t a, size_t b, Args... cs)
{
return variadic_max(std::max(a, b), cs...);
}
Before C++14, std::max()
isn't constexpr
, so that can be replaced with:
return variadic_max((a > b ? a : b), cs...);
One thing worth noting about:
maybe apply a
boost::static_visitor
to all types at compile time?
Visitation with a variant
is a runtime operation - your visitor gets called with the type that the variant
happens to be holding on to. It will not be called with all the types.
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