在枚举之前使用枚举

时间:2014-06-07 11:05:12

标签: c++ enums

我有一个带有在公共部分声明的枚举的C ++头文件:

enum Button {A, B, C, D};

使用该枚举作为私有部分中的模板参数的地图:

map<Button, int> bindings;

如果不是因为我喜欢在公共部分之前定义私有部分,那么这将完美地工作,因此编译器不会将Button识别为符号。我已经在地图声明工作之前检查并移动了Button声明。

这对我来说似乎是一个巨大的限制,我是否可以使用解决方法而无需翻转我的头文件的公共和私有部分?

4 个答案:

答案 0 :(得分:5)

你可以在C ++ 11中使用。

您不能只是向前声明枚举,因为编译器需要先知道枚举的大小才能使用枚举,枚举的大小取决于枚举的大小和值。

C ++ 11添加了新的语法,允许您告诉编译器枚举的大小:

enum <name> : <underlying_type>

所以你可以把你的课写成:

class Foo
{
public:
    enum Button : char;
private:
    map<Button, int> bindings;
public:
    enum Button : char
    {
        A,
        B,
        C,
        D
    };
};

但是,你仍然无法从公共部分获得前瞻声明。但是定义可以在地图声明之后出现。

答案 1 :(得分:3)

两个解决方案(都需要C ++ 11):

class S {
public:
    enum class Button;
private:
    std::map<Button, int> bindings;
public:
    enum class Button {A, B, C, D};
};

或者:

class S {
public:
    enum Button : int;
private:
    std::map<Button, int> bindings;
public:
    enum Button : int {A, B, C, D};
};

答案 2 :(得分:1)

使用枚举类或为枚举指定默认类型,然后您可以转发声明它。

E.g:

enum class Button;

但是,这个前瞻声明必须在私人部分。

顺便说一下private之前public非常奇怪。其他人使用的公共接口不应该在顶部吗?

答案 3 :(得分:0)

虽然我认为这可能是一个坏主意,但这是实现这一目标的一种方式,实际上确实可以避免甚至向你班级的任何公众成员发出前瞻声明:

class MyClass;
class MyClassPublic;
template <typename> class MyClassPrivate;

template <typename TPublic = MyClassPublic>
class MyClassPrivate : public TPublic
{
    map<typename TPublic::Button, int> bindings;
};

class MyClassPublic
{
public:
    enum Button { A, B, C, D };
};

class MyClass : public MyClassPrivate<>
{
};

它依赖于模板类分两个阶段处理的事实,一次是在模板定义时,一次是在模板实例化时。在模板定义时,允许对尚未定义的成员进行一些引用。