我主要是指C++03标准,但经过快速浏览,它也适用于C++11标准。
以下代码在VC++2010中成功编译并执行:
请注意使用
仔细观察后发现,问题在于标准中通过以下语法定义了
请注意,上述表单实际上被标准用于其他地方,例如在指定声明符id时使用:
以下代码在VC++2010中成功编译并执行:
template<typename T>
class CC {
public:
T f(T a) {
return a*a;
}
};
template<>
class ::CC<int> { //<--- ::CC<int> syntax allowed by VC++2010, but is it non-standard ?
public:
int f(int a) {
return a*a;
}
};
int main(int argc, _TCHAR* argv[])
{
::CC<int> c;
}
请注意使用
::CC<int>
语法来引用全局命名空间中定义的模板。这与NamespaceA::CC<int>
语法不同,其中::
运算符前面有一些内容。我尝试使用C++03标准中的语法解析此代码,但出现了错误,似乎标准只接受NamespaceA::CC<int>
形式在类头声明中使用。仔细观察后发现,问题在于标准中通过以下语法定义了
class-head
:class-head:
class-key identifier(optional) base-clause(optional)
class-key nested-name-specifier identifier base-clause(optional)
class-key nested-name-specifier(optional) template-id base-clause(optional)
由于nested-name-specifier
的形式为AA::bb::
,所以它不接受我的::CC
。
我的问题是,为什么C++标准不允许使用::CC
的形式?这只是我对标准语法的错误解释吗?正确的语法应该是这样的:
class-head:
...
class-key '::'(optional) nested-name-specifier(optional) template-id base-clause(optional)
请注意,上述表单实际上被标准用于其他地方,例如在指定声明符id时使用:
declarator-id:
id-expression
::(optional) nested-name-specifier(optional) class-name
::
,而CC
是标识符,...? - Columbo::
作为 nested-name-specifier。该语言中长期存在的错误(首次在2002年被识别)直到C++14才被修补。 - David Hammen