mardi 22 janvier 2019

Why isn't this constexpr in a variadic function template constant?

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