关于c ++:<:无法开始模板参数列表

<: cannot begin a template argument list

我得到一个错误<:不能在g++编译器上开始模板参数列表。代码

1
2
3
4
template<typename T> class SomeClass;
class Class;

SomeClass<::Class>* cls;


根据最大蒙克令牌化原理,一个有效的C++令牌必须收集/具有尽可能多的连续字符。

<:是有向图(符号[的另一种表示)。

1
2
3
4
5
6
                           Digraph  Equivalent
                              <:          [
                              :>          ]
                              <%          {
                              %>          }
                              %:          #

因此,SomeClass<::Class>* cls;被解释为SomeClass[:Class>* cls;,这没有任何意义。

解决方案:在<:之间添加空白。

1
2
3
4
  SomeClass< ::Class>* cls;
            ^
            |
           White Space

请尝试以下操作:

1
SomeClass< ::Class>* cls;

你可以在这个问题中找到更多关于有向图的信息。关于三角图的这个问题也会有帮助。


用C++ 11这个问题的答案有点改变。

前C ++ 11

在C++ 11之前,最大的MunCH规则用于词法分析,以避免歧义,并通过尽可能多的元素来形成有效的令牌来工作。

1
<::

生成以下令牌:

1
<: :

<:是一个有向图,翻译成[,所以你最终得到:

1
SomeClass[:Class>* cls;

这不是有效的代码。

我们可以通过进入C++标准部分EDOCX1×8预处理令牌来确认这种情况:

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.

并提供了几个例子,包括以下经典的最大芒奇问题:

[ 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

在C++ 11中,这种变化,为这个案例制定了一个规则,而C++ 11标准草案增加了以下内容:

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 <:.

分割2.5预处理令牌。所以这个代码将不再在C++ 11中产生和错误。

此更改来自缺陷报告:1104


在<字符周围加空格:

1
SomeClass < ::Class > * cls;

实际上你只需要把…和…分开,但我喜欢对称。