Создание шаблона класса? - PullRequest
0 голосов
/ 26 августа 2011

Вот мой код:

template<typename T, template<typename = T,typename =std::allocator<typename = T> > class Container= std::vector>
 class stack
 {
     public:
     Container<T> cont;
     stack()
     {

     }
 };

Если я заменю самую первую строку кода на приведенный ниже код, то это будет работать:

template<typename T, template<typename elem= T,typename =std::allocator<elem> > class Container= std::vector>

но я хочу спросить, что я прочитал, когда вы не используете параметр типа шаблона, тогда вы можете написать это: <typename=default_type> или <typename>. Также T в приведенном выше коде отображается в списке параметров шаблона шаблона Container (то есть параметр типа T виден во всем его пункте параметризации). В общем, я так думаю, что это должно работать. но это не так и выдает ошибку:

error: expression '<erroneous-expression> = <erroneous-expression>' is not a constant-expression
error: template argument 1 and 2 are invalid

Так может ли кто-нибудь объяснить, почему я вижу эти ошибки, что такое ошибочное выражение?

Ответы [ 2 ]

1 голос
/ 26 августа 2011

Если параметр шаблона сам является шаблоном, то его собственные параметры шаблона не используются или не релевантны в контексте внешнего шаблона, кроме как для определения «сигнатуры шаблона» параметра template-template. Следовательно, вам не нужны ни имена параметров, так как они не используются или не нужны. Вы можете просто сказать это:

template <typename T, template<typename, typename> class Container = std::vector>
class stack
{
  typedef Container<T, std::allocator<T> > CT;
  // ...
};

Здесь template <typename, typename> - это просто ожидаемая вами подпись шаблона класса Container.

В C ++ 11 вы можете работать лучше и разрешать более общие контейнеры с помощью шаблонов с переменными значениями:

template <typename T, template<typename...> class Container = std::vector> class stack;

[Для полноты:] Добавление типов по умолчанию в список параметров параметра шаблона также работает, и это означает, что вы можете опустить эти типы позже (как вы уже сделали):

template<typename = T, typename = std::allocator<T> > class Container

---> now we can say:

Container<T> x;  // use second default argument
Container<> y;   // use both default arguments

Чтобы ответить на ваш вопрос: Вы хотите указать по умолчанию в

 template <typename = T, typename = std::allocator<typename> > class Container
                                    ^^^^^^^^^^^^^^^^^^^^^^^^
                                            Error!!

, но std::allocator<typename> не является типом - это даже не допустимый синтаксис. Вы можете либо иметь параметр шаблона, который снова является шаблоном, то есть template <typename> = std::allocator, но это не будет соответствовать std::vector, либо у вас есть фактический тип:

template <typename = T, typename = std::allocator<T> > class Container
                                   ^^^^^^^^^^^^^^^^^
                                   OK, this is a type
0 голосов
/ 26 августа 2011

В списке параметров шаблона класса, если указать параметр шаблона шаблона , то параметр шаблона параметра шаблона шаблона не используется (фактически они нельзя использовать).Таким образом, вы можете пропустить упоминание даже их имен.

Итак, что вы должны сделать, это:

template<typename T, template<class,class> class Container= std::vector>
class stack
{
     Container<T, std::allocator<T> > cont;
};

То есть все, что требуется для параметра шаблона шаблона - это число параметрови информация, что их параметр (ы): тип или значение.

Вы также можете написать это для лучшей читаемости:

template<typename T, template<class U,class Allocator> class Container= std::vector>
class stack
{
     Container<T, std::allocator<T> > cont;
};

Что касается того, почему ваш первый код не являетсяработает из-за std::allocator<typename = T>, который должен быть просто std::allocator<T>.То есть это должно работать:

template<typename T, template<typename =T,typename =std::allocator<T> >  class Container= std::vector>

Смотрите здесь: http://ideone.com/eO8qT

Но тогда такие типы по умолчанию параметра шаблона шаблона даже не рассматриваются.Они игнорируются.

Теперь вы можете спросить, почему std::allocator<typename =T> не работает.Потому что его плохо сформировано.Как вы думаете, std::vector<typename =T> имеет смысл?Обратите внимание, что std::allocator и std::vector оба являются шаблоном класса, но Container не является шаблоном класса.Это параметр шаблона шаблона шаблона класса.Вот почему для этого допускается typename =T, а для шаблонов классов, таких как std::allocator.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...