Pavlo Muratov
Pavlo Muratov

Reputation: 317

Deducing template parameter types for each type in parameter pack

Let's say I have a type

template <class T, class U>
class Pass
{
};

I want to make a class that will accept a list of Pass objects, each with arbitrary T and U and make 3 std::tuples.

Something like this:

template<template <typename P1, typename P2> class... T>
    class Test
    {
    public:
        Test(T<P1, P2>... passes) {}

        std::tuple<T<P1, P2>...> tuple1;
        std::tuple<P1...> tuple2;
        std::tuple<P2...> tuple3;
    };

And then create an instance:

Test t{ Pass<int, float>(), Pass<int, int>(), Pass<std::string, float>() };

Is it possible?

Upvotes: 1

Views: 57

Answers (1)

Barry
Barry

Reputation: 303196

Yes:

template <typename... >
struct Test;

template <typename... T, typename... U>
struct Test<Pass<T, U>...>
{
    Test(Pass<T, U>...);

    std::tuple<Pass<T, U>...> tuple1;
    std::tuple<T...> tuple2;
    std::tuple<U...> tuple3;
};

template <typename... T, typename... U>
Test(Pass<T, U>...) -> Test<Pass<T, U>...>;

We need the deduction guide here because class template argument deduction only implicitly considers the primary template's constructors and the primary in this case has no constructors.


Note that this declaration:

template <template <typename P1, typename P2> class... T>
struct X { };

Means the same thing as this declaration:

template <template <typename, typename> class... T>
struct X { };

Which means a parameter pack of binary class templates - not specific types. Such a class template might be instantiated with:

X<Pass, std::pair, std::vector> x;

Upvotes: 4

Related Questions