似乎 clang++(我试过 clang 3.2)将模板类的名称视为实例化类,而不是类范围内任何事件的模板。比如下面的代码
template <template <class> class T>
class A {};
template <typename T>
class B {
A<B> member;
// ^---- clang++ treats B as an instantiated class
// but I want it to be a template here
// this code could compile in g++
};
int main()
{
B<int> b;
return 0;
}
我应该怎么做才能编译它?
最佳答案
C++03
以这种方式解析 B
(称为 injected-class-name,每个类的隐式声明成员,包括模板实例化)旨在提供便利。我从来没有见过它像那样妨碍!
要变通,通过在名称前添加 ::
来限定名称(如果需要,还可以添加命名空间的名称)。
template <typename T>
class B {
A< ::B> member; // whitespace required to prevent digraph; see comments
};
C++11
C++11 §14.6.1/1 指定(强调我的)
Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected- class-name can be used as a template-name or a type-name. When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type- specifier of a friend class template declaration, it refers to the class template itself. Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.
因此,如果在 C++11 下出现此问题,则为编译器错误。如上所述的解决方法。
注——为了对比,C++03中对应的段落是
Like normal (non-template) classes, class templates have an injected-class-name (clause 9). The injected- class-name can be used with or without a template-argument-list. When it is used without a template- argument-list, it is equivalent to the injected-class-name followed by the template-parameters of the class template enclosed in <>. When it is used with a template-argument-list, it refers to the specified class template specialization, which could be the current specialization or another specialization.
如您所见,已经有一种特殊情况允许标识符是类或模板,具体取决于它是否出现在模板名称中。他们只是增加了几个案例。
关于c++ - clang++ - 将模板类名视为类范围内的模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14291438/