我在使用g++编译器时遇到了一个错误 <: cannot begin a template argument list。
代码如下:
template<typename T> class SomeClass;
class Class;
SomeClass<::Class>* cls;
我在使用g++编译器时遇到了一个错误 <: cannot begin a template argument list。
代码如下:
template<typename T> class SomeClass;
class Class;
SomeClass<::Class>* cls;
使用C++11后,对于这个问题的答案有一些变化。
C++11之前
在C++11之前,最大匹配规则被用于词法分析中以避免歧义,并通过尽可能地获取尽量多的元素来形成有效令牌,导致了以下问题:
<::
<: :
[
,因此你最终得到的是:"SomeClass[:Class>* cls;
这不是有效的代码。
我们可以通过查看C++草案标准第2.4
节预处理标记来确认这一点,其中写道:
如果输入流已解析为预处理标记到给定字符,则下一个预处理标记是最长的字符序列,即使这会导致进一步的词法分析失败。
并提供了一些示例,包括以下经典的最大匹配问题:
[示例:程序片段x+++++y被解析为x ++ ++ + y,这违反了内置类型的增量运算符的约束,即使解析x ++ + ++ y可能会产生正确的表达式。 ——结束示例]
C++11
在C++11中,这种情况发生了变化,为此制定了一项规则,并在C++11草案标准中添加了以下内容:
否则,如果接下来的三个字符是<::,并且随后的字符既不是:也不是>,则<将作为预处理器标记单独处理,而不作为备选标记<:的第一个字符。
添加到第2.5
节预处理标记。因此,这段代码在C++11中不再产生错误。
这一变化来自缺陷报告:1104
在 < 字符周围添加空格:
SomeClass < ::Class > * cls;
>>
的修复是在第14.3
节中完成的,但<::
的修复是最大匹配规则的修改。因此,两个问题都很烦人,但是涉及的核心问题不同。我在我的回答中详细说明了这一点。 - Shafik Yaghmour