clang++ -在类作用域中将模板类名视为模板
clang++ - treat template class name as template in the class scope
似乎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
(称为inject -class-name,每个类的隐式声明成员,包括模板实例化)是为了方便。我从来没见过它这么碍事!要解决这个问题,可以通过在名称前面添加::
来限定名称(如果需要,还可以加上名称空间的名称)。
template <typename T>
class B {
A< ::B> member; // whitespace required to prevent digraph; see comments
};
<标题> c++ 11 h1> c++ 11§14.6.1/1指定(强调我的)
与普通(非模板)类一样,类模板也有一个注入的类名(第9条)。注入的类名可以用作模板名或类型名。当它与模板实参列表一起使用时,作为模板模板形参的模板实参,或作为友类模板声明的详细类型说明符的最后标识符,指的是类模板本身。否则,它相当于<>中所包含的类模板的template-name后跟模板参数。
因此,如果这个问题在c++ 11下出现,它是一个编译器错误。如上所述。
注意-为了比较,c++ 03中对应的段落是
与普通(非模板)类一样,类模板也有一个注入的类名(第9条)。注入的类名可以与模板参数列表一起使用,也可以不带模板参数列表。当不使用模板实参列表时,它相当于注入的class-name后跟<>中所包含的类模板的模板形参。当它与template-argument-list一起使用时,它引用指定的类模板特化,可以是当前的特化,也可以是另一个特化。
可以看到,已经有一种特殊情况允许标识符是类还是模板,这取决于它是否出现在模板名中。
标题>这是c++ 11中的不一致行为,因为c++ 11规定注入的类名(在类体中自动声明的名称)在传递给模板模板形参时是模板。所以你的代码应该只在c++ 03实现中失败。
但是现在没有必要打开关于这个的bug报告。我早就做过了
相关文章:
- 未在作用域中声明unordered_map
- 有没有一种方法可以在编译时获得作用域类名
- C++quit()函数中可能存在作用域问题
- 未在此作用域OpenCV3.4中声明cvSaveImage
- 全局作用域中函数指针的赋值
- 在类函数中初始化外部作用域变量
- 不同作用域中的静态变量和全局变量
- 是同一作用域的函数部分中的函数调用
- 未在此作用域中声明的函数和变量 (C++)
- 类作用域的类型别名"using":[何时]方法中的用法可以先于类型别名?
- 将作用域枚举转换为基础类型
- 表达式必须具有完整或无作用域的枚举图
- 在构造函数中输入对象时C++类成员作用域
- 无法让"std::enable_if"适用于无作用域枚举
- 为什么不能直接引用作用域枚举类成员,而不能为无作用域枚举生成类成员?
- 函数未在作用域中声明 / 如何结合使用 header.h、header.cpp 和 main.cpp?
- -fno-unwind-tables 和 -fno-async-unwind-tables 不起作用 NDK clang
- 使用 clang llvm 检查变量在任意源位置的作用域是否具有范围
- 如何找出一个变量是否在clang AST的特定源位置的作用域中
- clang++ -在类作用域中将模板类名视为模板