Частичная специализация параметра типа в классе шаблона с параметрами шаблона типа и шаблона

Я хочу специализировать параметр типа следующего класса шаблона, который имеет параметр типа и параметр шаблона шаблона:

template <
    typename T,
    template <typename E> class Foo
> class Bar;

Я пробовал каждую перестановку добавления и/или исключения .template и typename в последней строке каждого из следующих фрагментов, и ни один из них не компилируется:

1.)

template <
    template <typename E> class Foo
> class Bar<int, Foo<typename E>>;

2.)

template <
    template <typename E> class Foo
> class Bar<int, Foo.template <typename E>>;

3.)

template <
    template <typename E> class Foo
> class Bar<int, Foo<E>>;

4.)

template <
    template <typename E> class Foo
class Bar<int, Foo.template <E>>;

Почему ни один из них не работает?

Что касается последней строки каждого применимого фрагмента:

  • Разве typename не поясняет, что E — это тип, используемый классом Foo, или этот синтаксис может использоваться только в теле {} определения класса Bar?
  • Разве template не разъясняет, что Foo является шаблоном, и, следовательно, не позволяет компилятору анализировать Foo < как Foo "меньше чем", или этот синтаксис может использоваться только в теле {} определения класса Bar?

Как я могу заставить это работать?


person CodeBricks    schedule 25.05.2014    source источник


Ответы (2)


Разве typename не разъясняет, что E — это тип, используемый классом Foo, или этот синтаксис может использоваться только в теле {} определения класса Bar?

typename используется только тогда, когда вы определяете тип в определении шаблона (можно также использовать class) или когда вы обращаетесь к зависимому типу (типу, который зависит от параметра шаблона).

Для получения дополнительной информации (даже о том, когда используется template) см. эта тема.

Как я могу заставить это работать?

Имя типа в параметре шаблона шаблона фактически не может быть использовано. Это просто формальность. Вместо этого вы должны добавить еще один параметр шаблона в свой основной шаблон:

template <
    template<typename> class Foo,
    typename E
> class Bar<int, Foo<E>> { ... };

Более того, если это специализация шаблона Bar, то для специализации Bar нужен первичный шаблон:

template<typename T, typename U>
struct Bar;

template <
    template<typename> class Foo,
    typename E
> class Bar<int, Foo<E>> { ... };
person 0x499602D2    schedule 25.05.2014
comment
Не могли бы вы привести полный рабочий пример? Я последовал вашему предложению здесь, и либо я неправильно его истолковываю, либо нет. компилировать. Я включил еще одну закомментированную альтернативу, которая также не компилируется. - person CodeBricks; 26.05.2014
comment
+1, это то, что я хотел объяснить в первую очередь. - person Marco A.; 26.05.2014
comment
@CodeBricks Ваш основной шаблон неверен. Foo<E> — это тип, поэтому второй параметр в основном шаблоне должен быть таким же. см. здесь. - person 0x499602D2; 26.05.2014
comment
@ 0x499602D2 Ваше решение компилируется! Правильно ли я понимаю, что параметр типа E вашего основного шаблона специализирован для двух параметров: template <typename E> class Foo и typename E? - person CodeBricks; 26.05.2014
comment
@CodeBricks Нет. Имя параметра шаблона E является произвольным. На самом деле, поскольку это имя нигде не используется в основном шаблоне, его можно удалить, что приведет к template<typename, typename> class Bar;. Единственная специализация происходит во втором шаблоне, где имена шаблонов опять же не имеют ничего общего с определением первичного шаблона Bar. Единственное, что имеет значение, это то, как типы настраиваются в специализации. - person 0x499602D2; 26.05.2014
comment
Хм, в нынешнем виде этот вопрос не отвечает на вопрос ОП. Не могли бы вы отредактировать его, чтобы он содержал все соответствующие обсуждения, чтобы он стоял сам по себе? - person Kerrek SB; 26.05.2014
comment
Имя типа в параметре шаблона шаблона фактически не может быть использовано. -› Его можно использовать в некоторых ситуациях. - person Constructor; 26.05.2014
comment
@Constructor Какие именно ситуации ?? - person 0x499602D2; 26.05.2014
comment
@Constructor Оооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооочень приятно! Думаю, мне следовало сказать вне шаблона. :) - person 0x499602D2; 26.05.2014
comment
Да, я думаю так же, как и вы. :-) - person Constructor; 26.05.2014

Так:

template <template <typename E> class Foo>
class Bar<int, Foo>
{
    // ...
};

Вы даже можете опустить имя внутреннего параметра E, так как оно бесполезно.

person Kerrek SB    schedule 25.05.2014