假设我有以下代码:
template <template <typename> class T>
class A {};
template <typename T>
class B
{
A<B> instance;
};
int main()
{
B<int> instance;
}
gcc 4.7.2和gcc 4.8.0编译这段代码ok,而icc 13.0.1和clang 3.2给了我一个错误(clang require :: B而不是B,而icc在&lt; in template instantiaion之后也需要空格)。
谁是对的?
我找到了关于它的线程(Template class that refers to itself as a template template parameter?),但是我无法理解标准的14.6.1 / 2并且还看到了LLVM错误14350(http://www.mail-archive.com/llvmbugs@cs.uiuc.edu/msg21095.html)。那么,clang和intel在这里错了吗?
答案 0 :(得分:1)
inject-class-name可以用作模板名称或类型名称。当它与 template-argument-list 一起使用时,作为模板 template-parameter 的 template-argument ,或作为最终标识符在友元类模板声明的 elaborated-type-specifier 中,它引用了类模板本身。
“inject-class-name”是类模板的名称(B
)“注入”类的范围。换句话说,它指的是在类B
的定义中使用非限定名B
。如果在需要模板名称的上下文中使用该名称:即,使用显式模板参数(B<int>
)或作为采用模板模板参数(A<B>
)的模板的模板参数,它应该引用模板本身。
所以,gcc是对的。
此外,在C ++ 11中,<
中的<::B>
之后不需要空格。根据第2.5节第3段,将输入流分为令牌时:
如果接下来的三个字符为
<::
且后续字符既不是:
也不是>
,则<
本身会被视为预处理程序令牌,而不是备用标记<:
的第一个字符。 (<:
是撰写[
的另一种方式。)