Noah
Noah

Reputation: 1759

template with parameter pack AFTER default templated VALUE

Is it possible to have a default templated value before a templated parameter pack.

I.e:

#include <tuple>


template<int n = 0, typename... Pack>
struct bad {
    static constexpr int k_n = n;
    using pack_t             = std::tuple<Pack...>;
};
using success = bad<0, int, int>;
using fail = bad<int, int>; // Is there a way to achieve this?

Fails with:

error: template argument for non-type template parameter must be an expression
using fail = bad<int, int>;

Although it is documented that parameter packs may follow default templated parameters

Is there a way to get the equivelent behavior of:

using works = bad<int, int>;
static_assert(works::k_n == 0);
static_assert(std::is_same<works::pack_t, std::tuple<int, int>>::value); 

?

Upvotes: 0

Views: 57

Answers (1)

Bernd
Bernd

Reputation: 2221

It is not directly possible - but you can convert the non type template parameter to a type.

Something like:

#include <iostream>

template<auto v>
struct ValueWrapper
{
    constexpr static auto value = v;
};

template<typename... Pack>
struct common_bad{
    using pack_t = std::tuple<Pack...>;
};

template<typename... Pack>
struct bad : public common_bad<Pack...> 
{
    static constexpr int k_n = 0;
};


template<auto v, typename... Pack>
struct bad<ValueWrapper<v>, Pack...> : public common_bad<Pack...>
{
    static constexpr int k_n = ValueWrapper<v>::value;
};

using success = bad<ValueWrapper<10>, int, int>;
using fail = bad<int, int>;

int main() {
    std::cout << success::k_n << "\n";
    std::cout << fail::k_n << "\n";
}

Upvotes: 1

Related Questions