【发布时间】:2016-09-05 02:00:31
【问题描述】:
我主要指的是C++03标准,但粗略看了一下,它应该也适用于C++11标准。
以下代码在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)
注意,标准在其他地方确实使用了上述形式,例如,在指定 declarator-id 时:
declarator-id:
id-expression
::(optional) nested-name-specifier(optional) class-name
【问题讨论】:
-
当然嵌套名称说明符可以是
::,而CC是标识符,...? -
我注意到 C++11 在嵌套名称说明符中添加了一个前导 '::' 而 c++03 标准要求在 ':: 之前有一个类或命名空间名称'。可能是 C++03 中的一个“错误”
-
@JavaMan link 在另一个问题中(搜索“355.”,# is nonfunctional)似乎完全表明了这一点。尚不清楚它是否已在 C++11 或 14 中修复,甚至还没有。
-
@Columbo wg21.link/cwg1411
标签: c++ c++11 language-lawyer grammar c++03