In my class (which is a variadic class template), I need a constexpr for the sizeof() of the largest type passed in a variadic template. Like this:
template<class... Types>
class DiscriminatedUnion
{
.
.
.
static constexpr auto value = maxSizeOf<Types...>();
The code I have come up with for maxSizeOf() is the following:
template <class T>
static constexpr T static_max(T a, T b) {
return a < b ? b : a;
}
template <class T, class... Ts>
static constexpr T static_max(T a, Ts... bs) {
return static_max(a, static_max(bs...));
}
template <class T>
static constexpr int maxSizeOf() {
return sizeof(T);
};
template <class T, class... Ts>
static constexpr int maxSizeOf() {
return static_max(sizeof(T), maxSizeOf<Ts...>());
};
But in Visual Studio 2017, I am getting a compile error "expression did not evaluate to a constant."
I am not sure what it is that is not allowing the expression to be constant. I've tried compiling different things to ensure that they can be constant. I've tried using a sizeof() with a template parameter in a constexpr function, which works, which I expect since the size of types is always known at compile time. Integer arithmetic and comparison seems to be valid in a constexpr function, but I tried some again for verification. Then I've tried using integer arithmetic in the variadic template method, without sizeof(), with the following:
template <class T>
static constexpr int maxSizeOf(int n) {
return n;
};
template <class T, class... Ts>
static constexpr int maxSizeOf(int n) {
return static_max(n, maxSizeOf<Ts...>(n + 1));
};
static constexpr int numBytes = maxSizeOf<Types...>(1);
And this does not work. So I'm thinking it must be something to do with the variadic method template expansion. But this should be able to be made a compile-time constant, because variadic template packs are always expanded at compile time. Does anyone know why these can't be constexpr?
Aucun commentaire:
Enregistrer un commentaire