c ++ (g ++ - 4.x) проблема с шаблонами - PullRequest
8 голосов
/ 30 мая 2011

У меня есть этот простой код:

template<template <class> class Generator>
class TestHelper {};

template<class Writer>
class Test
{
    typedef TestHelper< Test >  Helper;  
};

Отлично работает на последних версиях g ++, но в 4.4 или 4.5 я получаю эту ошибку:

test.cpp:7: error: type/value mismatch at argument 1 in template parameter list for 'template<template<class> class Generator> class TestHelper' 
test.cpp:7: error:   expected a class template, got 'Test<Writer>'

Что я делаю не так?

Ответы [ 2 ]

12 голосов
/ 30 мая 2011

Это потому, что внутри тела класса Test<Writer> имя Test без предоставления аргументов шаблона автоматически принимает те же аргументы (например, Writer).

Например, это позволяет записатьскопируйте конструктор как:

Test(const Test&);

вместо

Test::Test(const Test<Writer>&);

Вы можете преодолеть это, указав Test с его пространством имен, например,

 typedef TestHelper< ::Test >  Helper;

ПРИМЕЧАНИЕ. Как предполагает Томалек, исходное использование действительно в C ++ 0x.Вот соответствующий абзац стандарта (выделенный мной) из раздела 14.6.1 ([temp.local]):

Как и обычные (не шаблонные) классы, шаблоны классов имеют инъецированный класс-имя (пункт 9).Введенное имя класса может использоваться как имя шаблона или имя типа . Когда он используется с списком аргументов шаблона , в качестве аргумента шаблона для шаблона параметр шаблона или как окончательный идентификатор в подробном спецификаторе типа объявления шаблона класса друга, относится к самому шаблону класса .В противном случае он эквивалентен template-name , за которым следует template-parameters шаблона класса, заключенного в <>.

1 голос
/ 30 мая 2011

@ Бен, вероятно, прав, но вот совершенно другой способ заставить его скомпилировать, который не использует шаблоны в качестве аргументов для шаблонов.

template<class Generator> // changed this to a simpler template
class TestHelper {};

template<class Writer>
class Test
{
            typedef TestHelper< typename Test :: Writer >  Helper; // 2nd change
};

Я сделал два изменения.@ Хьюго, может быть, это то, что вы хотели, а может, это то, что сделали старые версии g ++?

Получить код для компиляции легко, но это не значит, что он делает то, что, как вы думаете, делает!

...