Я получаю сообщение об ошибке <: не могу начать список аргументов шаблона в компиляторе g++. Код
template<typename T> class SomeClass;
class Class;
SomeClass<::Class>* cls;
Я получаю сообщение об ошибке <: не могу начать список аргументов шаблона в компиляторе g++. Код
template<typename T> class SomeClass;
class Class;
SomeClass<::Class>* cls;
В соответствии с принципом максимизации маркера Munch действительный токен С++ должен собирать/иметь как можно больше последовательных символов.
<:
является digraph (альтернативное представление символа [
).
Digraph Equivalent
<: [
:> ]
<% {
%> }
%: #
Итак, SomeClass<::Class>* cls;
интерпретируется как SomeClass[:Class>* cls;
, что не имеет никакого смысла.
Решение: добавьте пробел между <
и :
SomeClass< ::Class>* cls;
^
|
White Space
Попробуйте вместо этого:
SomeClass< ::Class>* cls;
Вы можете найти дополнительную информацию в этом вопросе о орграфах. Этот вопрос о триграфах также может быть полезен.
С С++ 11 ответ на этот вопрос немного изменится.
Pre С++ 11
Предшествующее до С++ 11 правило максимального munch, которое используется в лексическом анализе, чтобы избежать двусмысленностей и действий, принимая как можно больше элементов, чтобы сформировать действительный токен вызвал это:
<::
для создания следующих токенов как:
<: :
<:
- это орграф, который преобразуется в [
, и поэтому вы получаете:
SomeClass[:Class>* cls;
который недопустим.
Мы можем подтвердить, что это имеет место, перейдя в проект стандартного раздела С++ 2.4
Тоны предварительной обработки, в котором говорится:
Если входной поток проанализирован в токере предварительной обработки до заданный символ, следующий токен предварительной обработки - это самая длинная последовательность символов, которые могут составлять токен предварительной обработки, даже если что привело бы к дальнейшему лексическому анализу.
и предоставляет несколько примеров, включающих следующий классический максимальный вопрос с мэшем:
[Пример: фрагмент программы x +++++ y анализируется как x ++ ++ + y, который, если x и y имеют встроенные типы, нарушает ограничение на приращения, хотя анализ синтаксиса x ++ + ++ y может привести к правильное выражение. -end пример]
С++ 11
В С++ 11 это изменяется, для этого случая выведено правило, а проект С++ 11 добавил следующее:
В противном случае, если следующие три символа: <:: и последующие символ не является ни: nor > , < обрабатывается как токен препроцессора сам по себе, а не как первый символ альтернативного токена <:.
в раздел 2.5
Пункты предварительной обработки. Таким образом, этот код больше не будет производить и ошибки в С++ 11.
Это изменение произошло из отчета : 1104
Поместите пробелы вокруг < символы:
SomeClass < ::Class > * cls;
Вам просто нужно отделить < и:, но мне нравится симметрия.