<:无法开始模板参数列表

时间:2010-10-17 09:14:10

标签: c++ parsing templates c-preprocessor digraphs

我收到错误<:无法在g ++编译器上开始模板参数列表。代码

template<typename T> class SomeClass;
class Class;

SomeClass<::Class>* cls;

4 个答案:

答案 0 :(得分:34)

根据Maximal Munch tokenization principle,有效的C ++令牌必须收集/拥有尽可能多的连续字符。

<:digraph(符号[的替代表示)。

                           Digraph  Equivalent
                              <:          [
                              :>          ]
                              <%          {
                              %>          }
                              %:          #

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

解决方案:在<:

之间添加空格
  SomeClass< ::Class>* cls;
            ^
            | 
           White Space

答案 1 :(得分:11)

请尝试以下方法:

SomeClass< ::Class>* cls;

您可以在this有关有向图的问题中找到更多信息。关于三字母的This问题也可能有所帮助。

答案 2 :(得分:7)

使用C ++ 11,这个问题的答案会有所改变。

Pre C ++ 11

在C ++ 11之前,maximal munch rule用于词法分析,以避免歧义,并通过采用尽可能多的元素来形成有效令牌,这导致了这一点:

<::

生成以下标记:

<: :

<:是有向图,可转换为[,因此您最终得到:

SomeClass[:Class>* cls;

这是无效的代码。

我们可以通过转到草案C ++标准部分2.4 预处理令牌来确认这种情况,其中包含:

  

如果输入流已被解析为预处理令牌,则最多为a   给定字符,下一个预处理标记是最长的序列   可以构成预处理令牌的字符,即使   这将导致进一步的词汇分析失败。

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

  

[示例:程序片段x +++++ y被解析为x ++ ++ + y,   如果x和y是内置类型,则违反约束条件   增量运算符,即使解析x ++ + ++ y可能会产生一个   正确的表达。 - 例子]

C ++ 11

在C ++ 11中,这种情况发生了变化,针对这种情况制定了规则,draft C++11 standard添加了以下内容:

  

否则,如果接下来的三个字符是&lt; ::和后续字符   字符既不是:也不是>,&lt;被视为预处理程序令牌   它本身而不是替代标记的第一个字符&lt;:。

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

此更改来自defect report: 1104

答案 3 :(得分:2)

在&lt;周围放置空格。字符:

SomeClass < ::Class > * cls;

你实际上只需要分开&lt;并且:但我喜欢对称。