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).