【问题标题】:How can i manage a set of derived class enums without needing to instantiate the derived class?如何在不需要实例化派生类的情况下管理一组派生类枚举?
【发布时间】:2017-06-14 19:07:48
【问题描述】:

我试图理解为什么下面的代码 sn-p 不会编译:

template <class Derived> struct Base {
    const std::set<typename Derived::Foo> types() const { return theSet; }
    std::set<typename Derived::Foo> theSet;
};

struct Derived : Base<Derived> {
    enum Foo { X,Y,Z };
};

int main(int argc, char** argv) { Derived x; return 0; }

我收到一条错误消息,指出带有 types() const 的行是对不完整 struct Derived 的无效使用 - 但它只需要知道集合的类型是 Foo 枚举,所以我不是确定我理解错误,或者是否有一种方法不需要我制作int..

编译器的完整错误说:

error: invalid use of imcomplete type 'struct Derived'
    const std::set<typename Derived::Foo> types() const {
error: forward declaration of 'struct Derived'
struct Derived : Base<Derived>

【问题讨论】:

  • 在您的帖子中包含实际的错误消息总是有帮助的
  • 我想当编译器尝试实例化 Derived 类时,它会看到它是从 Base 派生的并将其实例化。但是此时 Derived 还没有完全实例化,所以编译器不知道 Derived::Foo 的类型是什么(std::set 不能用不完整的模板参数实例化)。
  • @DmitryGordon 有没有简单的方法解决这个问题?我担心我可能不得不使集合成为整数......
  • @CaptainObvlious 添加了它
  • 不要对模板参数和外部类型使用相同的名称。您确定要向我们展示整个代码吗?

标签: c++ templates inheritance gcc crtp


【解决方案1】:

要编译这个示例编译器需要一个嵌套类型的前向声明,这似乎是不可能的(参见How do I forward declare an inner class?)所以最简单的解决方法可能是让Base 类采用两个模板并将Foo 移出你的类定义:

#include <set>

template <class T, typename F> struct Base
{
    const std::set<F> types() const { return theSet; }
    std::set<F> theSet;
};

enum class Foo { X,Y,Z };

struct Derived : Base<Derived, Foo>
{
};

int main(int argc, char** argv)
{
    Derived x; return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 2011-01-21
    • 1970-01-01
    • 2015-01-30
    • 2013-05-20
    • 2020-08-16
    • 2010-12-15
    相关资源
    最近更新 更多