Klaus
Klaus

Reputation: 25593

default template argument and parameter pack

In a classic recursive template specialization I need one type multiple times in the class definition, e.g. for inheriting and using statement, maybe on other places also.

Example:

 template < typename ... T > 
class C;

template < typename FIRST, typename ... REST>
class C< FIRST, REST...>: public std::conditional_t< sizeof...(REST), C<REST...>, Empty >
{
    public:
    using std::conditional_t< sizeof...(REST), C<REST...>, Empty >::Set;
    void Set( FIRST );
};

As you can see, I need to write multiple times the std::conditional_t< sizeof...(REST), C<REST...>, Empty > expression.

The problem is, that I can`t either use

template < typename ... T >
class C;

template < typename FIRST, typename ... REST, typename INHERIT = std::conditional_t< sizeof...(REST), C<REST...>, Empty >>
class C< FIRST, REST...>: public INHERIT
{
    using INHERIT::Set;
};

fails because C++ did not allow default template parameters in specializations

nor

template < typename ... T, typename INHERIT = std::conditional_t< sizeof...(REST), C<REST...>, Empty >  >
class C;

...

fails because I can not use default template arguments behind a parameter pack. Even if this would be allowed, class C is not defined yet and as this C<REST...> will fail also.

Is there any trick to avoid to multiple define the std::conditional_t< sizeof...(REST), C<REST...>, Empty > statement?

Upvotes: 1

Views: 108

Answers (1)

Ted Lyngmo
Ted Lyngmo

Reputation: 117158

You could shorten the duplication down slightly by creating an alias template, here called mybase:

template <class... REST>
using mybase = std::conditional_t<sizeof...(REST), C<REST...>, Empty>;

template <typename FIRST, typename... REST>
class C<FIRST, REST...> : public mybase<REST...> {
public:
    using mybase<REST...>::Set;
    void Set(FIRST);
};

Upvotes: 3

Related Questions