【问题标题】:How to instantiate, by the standard, a class template containing nested subclass templates如何按照标准实例化包含嵌套子类模板的类模板
【发布时间】:2021-08-27 20:57:46
【问题描述】:

有一个模板声明

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),但 gcc 11.1 和 clang 12.0.0 无法编译它(gccclang 的链接)

我尝试使用不同的声明来实例化模板

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 个选项的事实是它的缺陷吗?

【问题讨论】:

标签: c++ templates language-lawyer


【解决方案1】:

这里有一些问题:

template <class C> struct MyData : Data<C> {
  MyData::Item1<int> item10;
};

MyData 在这里是一个不完整的类型,所以我们还不能以这种方式使用它。但是,由于Item1是继承自Data&lt;C&gt;,所以我们应该可以直接引用它:

Data<C>::Item1<int> item10;

但是现在Data&lt;C&gt;::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;

【讨论】:

    猜你喜欢
    • 2018-11-26
    • 1970-01-01
    • 2016-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 2019-01-06
    相关资源
    最近更新 更多