<: не может начать список аргументов шаблона
Я получаю ошибку <: не могу начать список аргументов шаблона на компиляторе 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
С 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;
Вам нужно только разделить <и:, но мне нравится симметрия.