Clang和Intel无法编译此CRTP代码
Clang and Intel fail to compile this CRTP code
我编写了一个使用了大量c++ 11元编程技术和CRTP的小库,它在g++ 4.7.2下可以很好地编译
现在,我尝试用Intel icpc 13.0.0.079编译它,它产生了数百个错误。所以我试着把问题一个接一个地分离出来。
所以,首先,考虑这段代码,在g++ 4.7.2 下编译没有问题#include <iostream>
template<template<typename> class Crtp, typename Type>
struct Base {};
template<typename Type>
struct Derived : public Base<Derived, Type>
{
Derived(): Base<Derived, Type>() {;}
};
int main()
{
Derived<int> x;
return 0;
}
icpc和clang都无法编译这段代码:
test_crtp.cpp(26): error: type "Derived<Type>::Derived" is not a class template
Derived(): Base<Derived, Type>() {;}
^
test_crtp.cpp(26): error: "Base" is not a nonstatic data member or base class of class "Derived<int>"
Derived(): Base<Derived, Type>() {;}
^
detected during instantiation of "Derived<Type>::Derived() [with Type=int]" at line 31
compilation aborted for test_crtp.cpp (code 2)
那么这是英特尔和clang中的错误,还是g++中的错误?如果是英特尔和clang的问题,你认为未来的版本会解决这个问题吗?
在类Derived
中,名称Derived
指的是(实例化的)类,而不是类模板。试着用Base< ::Derived, Type>
代替(注意在<和::)。>
在 c++模板完整指南 (Amazon)的9.2.3节中,有关于注入类名的讨论。引用:
类模板也有注入的类名。然而,他们比普通注入类名更奇怪:它们后面可以跟模板参数(在这种情况下,它们被注入类模板名称),但如果它们后面没有模板参数,则它们将类的形参表示为类的实参(或部分专门化(它的专门化参数)。这就解释了以下情况:
template<template<typename> class TT>
class X {};
template<typename T>
class C
{
Ca; // OK: same as ''C<T> a;''
C<void> b; // OK
X<C> c; // ERROR: C without a template argument list
// does not denote a template
X<::C> d; // ERROR: <: is an alternative token for [
X< ::C> e; // OK: the space between < and :: is required
}
注意非限定名是如何引用注入的名称而不是如果后面没有的列表,则视为模板的名称模板参数。为了补偿,我们可以强制的命名通过使用文件范围限定符::来查找的模板。其工作原理,但是我们必须小心不要创建一个所谓的有向图符号<:,它被解释为左括号。虽然相对罕见,这些错误会导致诊断混乱。
所以在你的代码中发生的是Base<Derived, Type>
被解释为Base<Derived<Type>, Type>
,这是病态的。因此,您需要使用范围限定符::
,并在<
之间加一个空格,以避免出现有向图。
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用CRTP确定生成代码
- c++模板代码顺序解析/CRTP
- 使用CRTP分离平台特定的代码
- Clang和Intel无法编译此CRTP代码