编译器的不同行为-模板-模板参数

Different behavior of compilers - template template argument

本文关键字:模板 参数 编译器      更新时间:2023-10-16

假设我有以下代码:

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在模板实例化中也需要<后面的空白)。

谁是对的?

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

14.6.1表示:

注入的类名可以用作模板名类型名。当它与模板参数列表一起使用时,作为模板的模板参数,或者作为友元类模板声明的精化类型说明符中的最终标识符时,它指的是类模板本身。

"注入的类名"是"注入"到类的作用域中的类模板(B)的名称。换句话说,它指的是在类B的定义中使用非限定名称B。如果在需要模板名称的上下文中使用该名称:即,使用显式模板参数(B<int>)或作为采用模板模板参数的模板的模板参数(A<B>),则该名称应指代模板本身。

所以,gcc是对的。

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

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