Home > Mobile >  Default value for template parameter, followed by non-type parameter pack
Default value for template parameter, followed by non-type parameter pack

Time:08-10

I'm struggling to make this code work

template <typename T, typename U = int, auto... Params>
class Foo {};

int main()
{
    auto foo1 = Foo<int, int, 1, 2, 3>{};
    auto foo2 = Foo<int, 1, 2, 3>{}; // I want it to compile
}

It looks like I need some hack. I tried partial specialization, but it doesn't work either

template <typename T, typename U, auto... Params>
class Foo {};

template <typename T, auto... Params>
class Foo<T, int, Params...> {};

int main()
{
    auto foo1 = Foo<int, int, 1, 2, 3>{};
    auto foo2 = Foo<int, 1, 2, 3>{}; // I want it to compile
}

I can't find anything closely related to this, help pls :)

CodePudding user response:

Unfortunately due to the way that template deduction works, this is ...not going to work.

Here's one alternative approach where the first template parameter is always a tuple, with one or two types, with the second type defaulting to an int:

#include <tuple>

template<typename T, auto ...Params> class Foo;

template<typename T, typename U, auto ...Params>
class Foo< std::tuple<T, U>, Params...> {

    // Your template goes here, making use of T and U
};

template<typename T, auto ...Params>
class Foo< std::tuple<T>, Params...> : Foo<std::tuple<T, int>, Params...> {

    // Might need to define some cleanups here, like a delegating constructor,
    // and/or delegated overload operators.

};

Foo<std::tuple<char>, 3, 4> defaulted;

Foo<std::tuple<char, float>, 3, 4> non_defaulted;

With a little bit more elbow grease it should be possible to require a formal std::tuple only when the 2nd optional type needs to be specified, and just specify the primary type directly (although that will create some avoidable confusion if the primary type is a std::tuple, itself).

  • Related