前向声明有问题:不完整类型'枚举::类别'用于嵌套名称说明符

时间:2016-11-18 14:09:10

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

我希望在enum周围有一个包装器,这将使我有机会将其转换为字符串,反之亦然。

基类如下:

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

如何解决这个问题?

1 个答案:

答案 0 :(得分:4)

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

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

enum Enum {
    Category1,
    Category2,
    OTHER
};

class Category : public StringConvertedEnum<Enum> {};

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

  

Flat比嵌套好。

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

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

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