Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<: cannot begin a template argument list

I get an error <: cannot begin a template argument list on g++ compiler. Code

template<typename T> class SomeClass;
class Class;

SomeClass<::Class>* cls;
like image 616
Pirate Avatar asked Oct 17 '10 09:10

Pirate


4 Answers

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
like image 190
Prasoon Saurav Avatar answered Oct 24 '22 06:10

Prasoon Saurav


Try the following instead:

SomeClass< ::Class>* cls;

You can find more info in this question about digraphs. This question about trigraphs could be helpful also.

like image 10
Kirill V. Lyadvinsky Avatar answered Oct 24 '22 06:10

Kirill V. Lyadvinsky


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

like image 7
Shafik Yaghmour Avatar answered Oct 24 '22 06:10

Shafik Yaghmour


Put spaces around the < characters:

SomeClass < ::Class > * cls;

You only actually need to separate < and :, but I like symmetry.

like image 1
JoshD Avatar answered Oct 24 '22 06:10

JoshD