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.