<: не может начать список аргументов шаблона - PullRequest
18 голосов
/ 17 октября 2010

Я получаю ошибку <: не могу начать список аргументов шаблона в компиляторе g ++. Код </p>

template<typename T> class SomeClass;
class Class;

SomeClass<::Class>* cls;

Ответы [ 4 ]

34 голосов
/ 17 октября 2010

Согласно принципу Maximal Munch действительный токен C ++ должен собирать / иметь как можно больше последовательных символов.

<: - это орграф (альтернативное представление символа [).

                           Digraph  Equivalent
                              <:          [
                              :>          ]
                              <%          {
                              %>          }
                              %:          #

То есть SomeClass<::Class>* cls; интерпретируется как SomeClass[:Class>* cls;, что не имеет никакого смысла.

Решение: Добавьте пробел между < и :

  SomeClass< ::Class>* cls;
            ^
            | 
           White Space
11 голосов
/ 17 октября 2010

Попробуйте вместо этого:

SomeClass< ::Class>* cls;

Более подробную информацию вы можете найти в этом вопросе о орграфах Этот вопрос о триграфах также может быть полезен.

7 голосов
/ 27 июля 2014

С C ++ 11 ответ на этот вопрос немного меняется.

Pre C ++ 11

Предыдущий C ++ 11 the Максимальное правило munch , которое используется в лексическом анализе, чтобы избежать двусмысленности и работает, беря как можно больше элементов для формирования действительного токена, вызвало это:

<::

для генерации следующих токенов как:

<: :

<: - это орграф, который переводится на [, и в результате вы получаете:

SomeClass[:Class>* cls;

, который не является допустимым кодом.

Мы можемподтвердите, что это так, перейдя к черновому стандартному разделу C ++ 2.4 токены предварительной обработки , в котором говорится:

Если входной поток был проанализирован в токены предварительной обработки доДля данного символа следующий токен предварительной обработки - это самая длинная последовательность символов, которая может составлять токен предварительной обработки, даже если это приведет к сбою в дальнейшем лексическом анализе.

и предоставляет несколько примеров, включая следующие классическиемаксимаl munch question:

[Пример: фрагмент программы x +++++ y анализируется как x ++ ++ + y, который, если x и y имеют встроенные типы,нарушает ограничение на операторы приращения, даже если синтаксический анализ x ++ + ++ y может привести к правильному выражению.- конец примера]

C ++ 11

В C ++ 11 это изменение было исключено для этого случая, а черновик стандарта C ++ 11 добавил следующее:

В противном случае, если следующие три символа являются <::, а последующий символ не является ни:, ни>, символ <обрабатывается как препроцессортокен сам по себе, а не как первый символ альтернативного токена <:. </p>

в секцию 2.5 токены предварительной обработки .Таким образом, этот код больше не будет выдавать ошибку C ++ 11.

Это изменение произошло из дефектного отчета: 1104

2 голосов
/ 17 октября 2010

Поставьте пробелы вокруг <символов: </p>

SomeClass < ::Class > * cls;

Вам нужно только разделить <и:, но мне нравится симметрия. </p>

...