I get an error <: cannot begin a template argument list on g++ compiler. Code
template<typename T> class SomeClass;
class Class;
SomeClass<::Class>* cls;
According to the Maximal Munch tokenization principle a valid C++ token must collect/have as many consecutive characters as possible.
<:
is a digraph (an alternative representation of symbol [
).
Digraph Equivalent
<: [
:> ]
<% {
%> }
%: #
So SomeClass<::Class>* cls;
is interpreted as SomeClass[:Class>* cls;
which doesn't make any sense.
Solution: Add a whitespace between <
and :
SomeClass< ::Class>* cls;
^
|
White Space
With C++11 the answer to this question changes a bit.
Pre C++11
Previous to C++11 the maximal munch rule which is used in lexical analysis to avoid ambiguities and works by taking as many elements as it can to form a valid token caused this:
<::
to generate the following tokens as:
<: :
<:
is a digraph which translates to [
and so you end up with:
SomeClass[:Class>* cls;
which is not valid code.
We can confirm that this is the case by going to the draft C++ standard section 2.4
Preprocessing tokens which says:
If the input stream has been parsed into preprocessing tokens up to a given character, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token, even if that would cause further lexical analysis to fail.
and provides a couple of examples including the following classical maximal munch question:
[ Example: The program fragment x+++++y is parsed as x ++ ++ + y, which, if x and y are of built-in types, violates a constraint on increment operators, even though the parse x ++ + ++ y might yield a correct expression. —end example ]
C++11
In C++11 this changes, a rule was carved out for this case and the draft C++11 standard added the following:
Otherwise, if the next three characters are <:: and the subsequent character is neither : nor >, the < is treated as a preprocessor token by itself and not as the first character of the alternative token <:.
to section 2.5
Preprocessing tokens. So this code will no longer produce and error in C++11.
This change came from defect report: 1104
Put spaces around the < characters:
SomeClass < ::Class > * cls;
You only actually need to separate < and :, but I like symmetry.
来源:https://stackoverflow.com/questions/3952648/cannot-begin-a-template-argument-list