【问题标题】:Trouble with forward declaration: incomplete type 'enums::Category' used in nested name specifier前向声明的问题:嵌套名称说明符中使用的类型“枚举::类别”不完整
【发布时间】:2016-11-18 14:09:09
【问题描述】:

我想对枚举有一个包装器,这将使我有机会将其转换为字符串,反之亦然。

基类如下:

template<typename TEnum>
class StringConvertedEnum {
public:
    static std::string toString(TEnum e);

    static TEnum toEnum(std::string &str);

protected:
    static const std::map<std::string, TEnum> _stringMapping;
    static const std::map<TEnum, std::string> _enumMapping;
};

然后我想要这样的东西:

class Category : public StringConvertedEnum<Category::Enum> {
public:
     enum Enum {
          Category1,
          Category2,
          OTHER
     };
};

但是目前它没有通过这个错误编译:

incomplete type 'enums::Category' used in nested name specifier

如何解决这个问题?

【问题讨论】:

标签: c++ c++11 enums c++14 crtp


【解决方案1】:

因为Enum 是在您的类中声明的,所以当您指定Category 继承StringConvertedEnum 时,它在其声明之前并不存在。这是一个不完整的类型,请参阅标准 "3.3.2 Point of declaration [basic.scope.pdecl]" 的相关部分(感谢 AndyG 在 cmets 中指出这一点)。

解决问题最简单的方法是在Category之外声明Enum

enum Enum {
    Category1,
    Category2,
    OTHER
};

class Category : public StringConvertedEnum<Enum> {};

这跟在Zen of Python 后面,即使我们谈论的是 C++:

平面比嵌套好。

第二种最简单的方法是声明一个基类:

class BaseCategory {
public:
    enum Enum {
        Category1,
        Category2,
        OTHER
    };
};
class Category : public BaseCategory, public StringConvertedEnum<BaseCategory::Enum> {};

正如 cmets 中所指出的,如果您使用的是现代 C++,则应该考虑 scoped enums

【讨论】:

  • +1。枚举是不完整的类型。相关标准:“3.3.2 声明点 [basic.scope.pdecl]”此外,OP 应该使用范围枚举,因为它们使用的是 C++11
  • @AndyG Thx 将其添加到答案中
  • 谢谢,但我不确定我是否了解范围枚举如何帮助解决这个问题。如果您在回答中澄清它会很好。
  • @silent_coder 作用域枚举无助于解决这个问题。这只是声明枚举的一种更安全的方式
猜你喜欢
  • 2014-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
  • 1970-01-01
  • 2021-07-25
  • 1970-01-01
相关资源
最近更新 更多