0

假设我有以下代码:

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 编译这段代码没问题,而 icc 13.0.1 和 clang 3.2 给了我一个错误(clang 需要 ::B 而不是 B,而 icc 在模板实例化中也需要空格)。

谁是对的?

我找到了关于它的线程(将自身称为模板模板参数的模板类?),但我无法理解标准的 14.6.1/2 并且还看到了 LLVM 错误 14350(http://www.mail- archive.com/llvmbugs@cs.uiuc.edu/msg21095.html)。那么,clang 和 intel 错了吗?

4

1 回答 1

1

14.6.1 说:

注入的类名可以用作模板名类型名。当它与template-argument-list一起使用时,作为模板模板参数的模板参数,或作为朋友类模板声明的详细类型说明符中的最终标识符,它指的是类模板本身.

“injected-class-name”是类模板的名称(B)“注入”到类的范围内。换句话说,它是指B在类的定义中使用非限定名称B。如果您在需要模板名称的上下文中使用该名称:即,使用显式模板参数 ( B<int>) 或作为带有模板模板参数 ( A<B>) 的模板的模板参数,它应该引用模板本身。

所以,gcc 是对的。

<此外,在 C++11 中, in之后不需要空格<::B>。根据第 2.5 节第 3 段,将输入流划分为令牌时:

如果接下来的三个字符是<::且后续字符既不是:也不是>,则<它本身被视为预处理器标记,而不是替代标记的第一个字符<:。(<:是另一种写作方式[。)

于 2013-02-14T19:54:34.237 回答