我想做的事情如下:

enum E;

void Foo(E e);

enum E {A, B, C};

编译器拒绝它。我在谷歌上快速浏览了一下,共识似乎是“你做不到”,但我不明白为什么。有人能解释一下吗?

澄清2:我这样做是因为我在一个类中有私有方法,它采用所说的枚举,我不希望枚举的值暴露出来-因此,例如,我不希望任何人知道E被定义为

enum E {
    FUNCTIONALITY_NORMAL, FUNCTIONALITY_RESTRICTED, FUNCTIONALITY_FOR_PROJECT_X
}

项目X不是我想让我的用户知道的东西。

所以,我想要转发声明枚举,这样我就可以把私有方法放在头文件中,在cpp中内部声明枚举,并将构建的库文件和头分发给人们。

至于编译器——它是GCC。


当前回答

对于iOS/Mac/Xcode上面临这种情况的人,

如果你在XCode中用Objective-C集成C/ c++头文件时遇到这个问题,只需将文件扩展名从。mm更改为。m即可

其他回答

我只是注意到,原因实际上是,在向前声明后,enum的大小还不知道。你使用一个结构的前向声明来传递一个指针,或者从一个在前向声明的结构定义本身中引用的地方引用一个对象。

向前声明枚举不是很有用,因为人们希望能够按值传递枚举。你甚至不能有指向它的指针,因为我最近被告知一些平台使用不同大小的指针用于char和int或long。所以这一切都取决于枚举的内容。

当前的c++标准明确禁止这样做

enum X;

(在7.1.5.3/1)。但下一个c++标准将于明年发布,允许以下功能,这让我确信问题实际上与底层类型有关:

enum X : int;

它被称为“不透明”枚举声明。您甚至可以在以下代码中按值使用X。并且它的枚举数可以稍后在枚举的重新声明中定义。参见当前工作草案中的7.2。

这样我们就可以forward declare enum

enum A: int;

详情请参阅连结。

在GCC中似乎不能前向声明!

这里有一个有趣的讨论。

可以将枚举包装在结构体中,添加一些构造函数和类型转换,然后前向声明结构体。

#define ENUM_CLASS(NAME, TYPE, VALUES...) \
struct NAME { \
    enum e { VALUES }; \
    explicit NAME(TYPE v) : val(v) {} \
    NAME(e v) : val(v) {} \
    operator e() const { return e(val); } \
    private:\
        TYPE val; \
}

这似乎是有效的: http://ideone.com/TYtP2

我会这样做:

[在公共标头中]

typedef unsigned long E;

void Foo(E e);

[在内部头文件中]

enum Econtent { FUNCTIONALITY_NORMAL, FUNCTIONALITY_RESTRICTED, FUNCTIONALITY_FOR_PROJECT_X,
  FORCE_32BIT = 0xFFFFFFFF };

通过添加FORCE_32BIT,我们可以确保Econtent编译成一个long,这样它就可以和E。