Как обернуть «расширенные параметры шаблона переменной»? - PullRequest
1 голос
/ 24 января 2012

C ++ 03 позволяет создать шаблонный класс, который наследуется от параметров шаблона:

// c++03 

struct NullType {};

template <class T0, class T1 = NullType, class T2 = NullType>
class Collector : public T0, public T1, public T2
{
};

template <class T0, class T1>
class Collector<T0, T1, NullType> : public T0, public T1
{
};

template <class T0>
class Collector<T0, NullType, NullType> : public T0
{
};

So

typedef Collector<A, B, C> X;

эквивалентно

class X: public A, public B, public C {};

C ++ 11 позволяет сделать это проще:

// variadic templates - great thing!
template <class ... Classes>
class C11_Collector :
    public Classes ...
{
};

Сборщик оберток должен обернуть параметры шаблона перед наследованием:

template <template <class> class Wrap, class T0, class T1 = NullType, class T2 = NullType>
class Wrapping_Collector : public Wrap<T0>, public Wrap<T1>, public Wrap<T2>
{
};

template <template <class> class Wrap, class T0, class T1>
class Wrapping_Collector<Wrap, T0, T1, NullType> : public Wrap<T0>, public Wrap<T1>
{
};

template <template <class> class Wrap, class T0>
class Wrapping_Collector<Wrap, T0, NullType, NullType> : public Wrap<T0>
{
};

So

typedef Wrapping_Collector<W, A, B> X;

эквивалентно

class X: public W<A>, public W<B> {};

Как реализовать Wrapping_Collector более простым способом с помощью c ++ 11?

Ответы [ 2 ]

2 голосов
/ 24 января 2012

Можно ли просто принудительно установить Wrap<NullType> как пустой класс?Тогда вы можете просто напрямую использовать

template <template <typename> class Wrap, typename... Types>
class Wrapping_Collector : public Wrap<Types>... {
   //...
};

В качестве альтернативы, если цепочка двойного наследования вместо прямого мульти-наследования подходит, вы можете сделать Wrapping_Collector<Wrap, A, B...> производным от Wrapping_Collector<Wrap, B...> и * 1008.*:

template <template <typename> class Wrap, typename... Types>
class Wrapping_Collector;

// The normal case
template <template <typename> class Wrap, typename Head, typename... Rest>
class Wrapping_Collector<Wrap, Head, Rest...>
    : public Wrapping_Collector<Wrap, Rest...>, Wrap<Head>
{
    //...
};

// Ignore on NullType
template <template <typename> class Wrap, typename... Rest>
class Wrapping_Collector<Wrap, NullType, Rest...>
    : public Wrapping_Collector<Wrap, Rest...>
{
    //...
};

// Base case
template <template <typename> class Wrap>
class Wrapping_Collector<Wrap> {};
1 голос
/ 25 января 2012

Я полагаю, вы бы сделали это в C ++ 11:

// variadic templates - great thing!
template <template <class> class Wrap, class... Classes>
class C11_Wrapping_Collector : public Wrap<Classes>... 
{
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...