<: не может начать список аргументов шаблона

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

template<typename T> class SomeClass;
class Class;

SomeClass<::Class>* cls;

4 ответа

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

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

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

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

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

  SomeClass< ::Class>* cls;
            ^
            | 
           White Space

Вместо этого попробуйте следующее:

SomeClass< ::Class>* cls;

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

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

Pre C++11

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

<::

генерировать следующие токены как:

<: :

<: это орграф, который переводится как [ и так вы в конечном итоге:

SomeClass[:Class>* cls;

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

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

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

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

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

C++11

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

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

в раздел 2.5 Предварительная обработка токенов. Так что этот код больше не будет выдавать ошибку C++11.

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

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

SomeClass < ::Class > * cls;

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

Другие вопросы по тегам