如何按照标准实例化包含嵌套子class模板的class模板
How to instantiate, by the standard, a class template containing nested subclass templates
有模板声明
template<class C> struct Data {
template<typename T> struct Item1 {
void Test() {
}
};
};
使用带有编译选项 /std:c++latest 的 MSVC v19.28,我尝试按如下方式实例化模板:
template<class C> struct Data {
template<typename T> struct Item1 {
void Test() {
}
};
};
template <class C> struct MyData : Data<C> {
MyData::Item1<int> item10; // (1)
};
struct S;
MyData<S> dataS;
代码已使用 MSVC 成功编译(参见 link), but gcc 11.1 and clang 12.0.0 could not compile it (links for gcc and clang)
我尝试使用不同的声明实例化模板
template <class C> struct MyData : Data<C> {
MyData::Item1<int> item10; // (1)
Data<C>::Item1<int> item11; // (2)
Data<C>::template Item1<int> item12; // (3)
};
MSVC 编译所有这些,但 gcc 和 clang 不编译。
我“找到”了一个 solution,它“适用于”所有提到的编译器
template<typename C, typename T> struct Item2 {
void Test() {
}
};
template<class C> struct Data {
};
template <class C> struct MyData : Data<C> {
Item2<C, int> item20;
};
struct S;
MyData<S> dataS;
它使用独立模板。
如何声明原始模板实例化符合C++标准?
MSVC 编译了所有 3 个选项,这是它的缺陷吗?
这里有一些问题:
template <class C> struct MyData : Data<C> {
MyData::Item1<int> item10;
};
MyData
在这里是一个不完整的类型,所以我们还不能那样使用它。但是,由于Item1
继承自Data<C>
,我们应该可以直接引用它:
Data<C>::Item1<int> item10;
但是现在,Data<C>::Item1
是一个依赖类型,所以我们需要使用typename
来告诉编译器它实际上是一个类型:
typename Data<C>::Item1<int> item10;
最后,因为Item1
是依赖类型的模板成员,我们还需要告诉编译器它是一个模板(相对于常量或其他东西)。
typename Data<C>::Item1 template<int> item10;
最后,我们降落在:
template<class C> struct Data {
template<typename T> struct Item1 {
void Test() {
}
};
};
template <class C>
struct MyData : Data<C> {
typename Data<C>::template Item1<int> item10;
};
struct S;
MyData<S> dataS;
有模板声明
template<class C> struct Data {
template<typename T> struct Item1 {
void Test() {
}
};
};
使用带有编译选项 /std:c++latest 的 MSVC v19.28,我尝试按如下方式实例化模板:
template<class C> struct Data {
template<typename T> struct Item1 {
void Test() {
}
};
};
template <class C> struct MyData : Data<C> {
MyData::Item1<int> item10; // (1)
};
struct S;
MyData<S> dataS;
代码已使用 MSVC 成功编译(参见 link), but gcc 11.1 and clang 12.0.0 could not compile it (links for gcc and clang)
我尝试使用不同的声明实例化模板
template <class C> struct MyData : Data<C> {
MyData::Item1<int> item10; // (1)
Data<C>::Item1<int> item11; // (2)
Data<C>::template Item1<int> item12; // (3)
};
MSVC 编译所有这些,但 gcc 和 clang 不编译。
我“找到”了一个 solution,它“适用于”所有提到的编译器
template<typename C, typename T> struct Item2 {
void Test() {
}
};
template<class C> struct Data {
};
template <class C> struct MyData : Data<C> {
Item2<C, int> item20;
};
struct S;
MyData<S> dataS;
它使用独立模板。
如何声明原始模板实例化符合C++标准? MSVC 编译了所有 3 个选项,这是它的缺陷吗?
这里有一些问题:
template <class C> struct MyData : Data<C> {
MyData::Item1<int> item10;
};
MyData
在这里是一个不完整的类型,所以我们还不能那样使用它。但是,由于Item1
继承自Data<C>
,我们应该可以直接引用它:
Data<C>::Item1<int> item10;
但是现在,Data<C>::Item1
是一个依赖类型,所以我们需要使用typename
来告诉编译器它实际上是一个类型:
typename Data<C>::Item1<int> item10;
最后,因为Item1
是依赖类型的模板成员,我们还需要告诉编译器它是一个模板(相对于常量或其他东西)。
typename Data<C>::Item1 template<int> item10;
最后,我们降落在:
template<class C> struct Data {
template<typename T> struct Item1 {
void Test() {
}
};
};
template <class C>
struct MyData : Data<C> {
typename Data<C>::template Item1<int> item10;
};
struct S;
MyData<S> dataS;