g ++ обрабатывают проблему по шаблону

Я портирую свой код окон C++ (msvc и Intel) к Linux (g ++). Код использует много шаблонов (мне нравится метапрограммирование ;-). Но я не могу скомпилировать этот код:

template <class TA>
struct A
{
    template <class TAB> struct B;
};


template <class TC>
struct C {};


template <class TD>
struct D
{
    template <class TTD> class T {};
};


template<class TA>
    template<class TBA>
struct A<TA>::B : C<typename D<TA>::T<TBA> >
{
    int foo;
};

g ++ говорит мне что в определении A:: B, C класс имеет недопустимые аргументы шаблона. Но на msvc и Intel это работает хорошо! Какова проблема здесь? PS: Извините, я не могу отправить исходный код, потому что он является слишком сложным шаблоном. Но этот пример является фактически тем же и дает ту же ошибку на g ++.Спасибо.

ОБНОВЛЕНИЕ: я нашел, что проблема находится в аргументе TBA T. g ++ doensn't как использование второго шаблона в определении.

6
задан f0b0s 25 June 2010 в 19:52
поделиться

1 ответ

Вам нужен шаблон ключевое слово

template<class TA>
    template<class TBA>
struct A<TA>::B : C<typename D<TA>::template T<TBA> >
{
    int foo;
};

GCC правильный, чтобы дать здесь диагностику. Это связано с тем, что T не может быть найден в зависимой области D . Значение < после него зависит от того, является ли T шаблоном или нет. Стандарт говорит, что T не должен рассматриваться как шаблон, и поэтому за T не может следовать список аргументов шаблона.

шаблон похож на typename в том смысле, что он сообщает компилятору обрабатывать T как шаблон, а < является началом аргумента. список на всякий случай. В Стандарте говорится в параграфах 14.2 / 2 и 14.2 / 4

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

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

В вашем случае T появляется после спецификатора вложенного имени D , который зависит от параметра шаблона TA . Для правильного анализа спецификатора имени-типа конструкция D :: T должна интерпретировать T как имя шаблона класса, который 14.2 запрещает.


По этой теме всегда неплохо попробовать и скомпилировать с помощью Clang

main1.cpp:21:37: error: use 'template' keyword to treat 'T' as a dependent template name
struct A<TA>::B : C<typename D<TA>::T<TBA> >
                                    ^
                                    template 
1 error generated.
10
ответ дан 10 December 2019 в 00:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: