我想做的事情如下:

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。


当前回答

我会这样做:

[在公共标头中]

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。

其他回答

我会这样做:

[在公共标头中]

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。

从c++ 11开始,枚举的前向声明是可能的。以前,枚举类型不能前向声明的原因是枚举的大小取决于它的内容。只要应用程序指定了枚举的大小,它就可以被前向声明:

enum Enum1;                     // Illegal in C++03 and C++11; no size is explicitly specified.
enum Enum2 : unsigned int;      // Legal in C++11.
enum class Enum3;               // Legal in C++11, because enum class declarations have a default type of "int".
enum class Enum4: unsigned int; // Legal C++11.
enum Enum2 : unsigned short;    // Illegal in C++11, because Enum2 was previously declared with a different type.

这样我们就可以forward declare enum

enum A: int;

详情请参阅连结。

[我的答案是错误的,但我把它留在这里,因为评论很有用]。

前向声明枚举是非标准的,因为指向不同枚举类型的指针不能保证大小相同。编译器可能需要查看定义才能知道该类型可以使用哪些大小指针。

实际上,至少在所有流行的编译器上,指向枚举的指针的大小是一致的。例如,枚举的前向声明是由Visual c++作为语言扩展提供的。

在c++ 11中,你可以前向声明一个枚举,只要同时声明它的存储类型。语法如下所示:

enum E : short;
void foo(E e);

....

enum E : short
{
    VALUE_1,
    VALUE_2,
    ....
}

事实上,如果函数从未引用枚举的值,那么此时根本不需要完整的声明。

g++ 4.6及以后的版本(-std=c++0x或-std=c++11在最近的版本中)都支持这一点。Visual c++ 2013支持此功能;在早期版本中,它有一些我还没有弄清楚的非标准支持-我发现了一些建议,简单的向前声明是合法的,但您的哩数可能会有所不同。