我收到错误<:无法在g ++编译器上开始模板参数列表。代码
template<typename T> class SomeClass;
class Class;
SomeClass<::Class>* cls;
答案 0 :(得分:34)
根据Maximal Munch tokenization principle,有效的C ++令牌必须收集/拥有尽可能多的连续字符。
<:
是digraph(符号[
的替代表示)。
Digraph Equivalent
<: [
:> ]
<% {
%> }
%: #
所以SomeClass<::Class>* cls;
被解释为SomeClass[:Class>* cls;
,这没有任何意义。
解决方案:在<
和:
SomeClass< ::Class>* cls;
^
|
White Space
答案 1 :(得分:11)
答案 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;并且:但我喜欢对称。