Goofy
Goofy

Reputation: 5387

How to apply template template parameters in case of variadic template

I'm working on template MyTemplate that is going to be used in following way:

using Alias = MyTemplate<std::pair<int, char>,
                         std::pair<int, double>,
                         std::pair<int, unsigned int>>;

For now we can assume that MyTemplate will take only list of pair types. Moreover, all pair types should have the same first type and second type have to vary.

I want to "catch" the pairs' first_type in MyTemplate. I came up with following definition:

template<typename... Ts>
struct MyTemplate
{
   using first_type = std::decay_t<decltype((Ts::first_type, ...))>;
   // ...
};

When I use typename MyTemplate::first_type in context of different template everything works fine. I only get a warning:

warning: left operand of comma operator has no effect [-Wunused-value]
    using first_type = std::decay_t<decltype((Ts::first_type, ...))>;
                                                                    ^

However, I cannot create instance of Alias because I get that error:

error: missing 'typename' prior to dependent type name 'std::pair<int, char>::first_type'

Do you gave any idea for "generic" solution? I can use C+17.

Upvotes: 1

Views: 67

Answers (1)

max66
max66

Reputation: 66210

For now we can assume that MyTemplate will take only list of pair types. Moreover, all pair types should have the same first type and second type have to vary.

I want to "catch" the pairs' first_type in MyTemplate.

Not sure but it seems to me that your looking something as follows

template <typename...>
struct MyTemplate;

template <typename FT, typename ... STs>
struct MyTemplate<std::pair<FT, STs>...>
 {
   using first_type = FT;
 };

You can verify

using Alias = MyTemplate<std::pair<int, char>,
                         std::pair<int, double>,
                         std::pair<int, unsigned int>>;

static_assert( std::is_same<int, typename Alias::first_type>::value, "!" );

This way you also impose that the template parameters of MyTemplate are all std::pairss with a common first_type.

Otherwise, without template specialization and maintaining you way, you can use std::tuple/std::tuple_element_t

template <typename ... Ts>
struct MyTemplate
 {
   using first_type = std::tuple_element_t<0, std::tuple<typename Ts::first_type...>>;
 };

Upvotes: 3

Related Questions