C++ Clang和Intel未能编译此CRTP代码
我编写了一个小型库,它使用了大量的C++11元编程技术和CRTP,并且可以很好地使用g++4.7.2进行编译C++ Clang和Intel未能编译此CRTP代码,c++,templates,c++11,compiler-errors,crtp,C++,Templates,C++11,Compiler Errors,Crtp,我编写了一个小型库,它使用了大量的C++11元编程技术和CRTP,并且可以很好地使用g++4.7.2进行编译 #include <iostream> template<template<typename> class Crtp, typename Type> struct Base {}; template<typename Type> struct Derived : public Base<Derived, Type> {
#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;
}
现在,我尝试用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;
}
#包括
模板
结构基{};
模板
结构派生:公共基
{
派生():基(){;}
};
int main()
{
导出x;
返回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)
test\u crtp.cpp(26):错误:类型“派生::派生”不是类模板
派生():基(){;}
^
test_crtp.cpp(26):错误:“Base”不是类“派生”的非静态数据成员或基类
派生():基(){;}
^
在第31行实例化“派生::派生()[with Type=int]”时检测到
为test_crtp.cpp(代码2)中止编译
那么,这是英特尔和clang中的一个bug,还是g++中的bug?如果是在intel和clang中,您认为它会在将来的版本中得到解决吗?在类
派生的中,名称派生的指的是(实例化的)类,而不是类模板。尝试使用Base<::派生,键入>
(注意在<和:::)之间留一个空格。在《C++模板完整指南》()的第9.2.3节中,有一个关于注入类名的讨论。引述:
类模板还注入了类名。然而,他们是
比普通注入类名称更奇怪:它们后面可以跟
模板参数(在这种情况下,它们被注入类模板
名称),但如果后面没有模板参数,则
将类的参数表示为其参数(或,对于
部分专门化,它的专门化参数)。这就解释了
以下情况:
模板
类X{};
模板
C类
{
Ca;//确定:与“Ca;”相同
cb;//好的
X c;//错误:c没有模板参数列表
//不表示模板
xd;//错误:e;//确定:<和::之间的空格是必需的
}
请注意,非限定名称是如何引用注入名称的,而不是
如果模板的名称后面没有
模板参数。为了补偿,我们可以强制使用
要使用文件范围限定符找到的模板:。这很有效,
但我们必须小心不要创建所谓的有向图标记
这是一个很好的问题,但通常CRTP不需要模板参数,只需要让派生类传递类型<代码>模板结构库;派生的模板结构:基<派生>{…}代码>更为正常…如果您想传播类型
,可能是您可以在派生的
中有一个类型定义
,它公开了它…标识符派生的
名称,在它自己的类中,完整的类型派生的
。这称为注入的类名。我认为这是GCC的一个错误。+对于一个好问题,我希望看到一个明确的答案too@Xeo:有没有办法在类中获取非完整类型?注意:之所以有空格,是因为在C++11中,您可以只编写@MatthieuM。还要注意,C++ C++ 11(或GCC<4.8)=@ XEO:这才是真正的C++:谢谢!我有几次偶然发现了它,这让我非常沮丧:(我从来没有使用过这种语法,所以你能描述一下“:”的确切含义吗?:“在这种情况下(或者发布一个指向它的教程/解释的链接)。