C++11 枚举转发导致 "underlying type mismatch"

C++11 Enum forward causes "underlying type mismatch"

我在 C++11 中工作,包括一个在 C++03 中实现的 h 文件。在我包含的 h 文件中,定义了一个枚举 Foo。我想在 code.h 中声明它的转发并在 code.cpp:

中使用它

header.h:

enum Foo {A=1};

code.h:

enum Foo : int; // also tried : unsigned int, long, short, unsigned short, char, unsigned char
void bar(Foo foo);

code.cpp:

#include header.h
void bar(Foo foo) { }

这是我在编译时遇到的错误(已测试 g++ 4.8.5 和 g++ 5.3.1):

In file included from code.cpp:2:0:
header.h:1:6: error: underlying type mismatch in enum ‘enum Foo’
 enum Foo {A=1};
      ^
In file included from code.cpp:1:0:
code.h:3:12: error: previous definition here
 enum Foo : int;

如果我将 header.h 更改为:

,我可以修复此错误
enum Foo : int {A=1};

但我不拥有 header 并且无法更改它。从表面上看错误,听起来我只需要知道 g++ 将什么类型用于未指定基础类型的枚举,然后在我的转发中使用该类型。

Even this simple example doesn't work :

#include <iostream>
#include <string>
#include <type_traits>

enum Foo {A=1};
enum Foo : unsigned; // : std::underlying_type<Foo>::type also doesn't work

int main()
{

  std::cout << "Hello, world\n";
}

如果你在前向声明中给它一个固定的基础类型,你只能前向声明一个枚举。此外,枚举的定义必须使用 相同 固定基础类型。

您的问题是您在 header.h 中的枚举定义没有基础类型,但后面的前向声明有一个。他们两个必须有一个。

似乎没有任何方法可以做到这一点,即使您指定了与编译器为您的 C++03 选择的完全相同的底层类型-样式 enum

示例:编译以下代码...

enum Foo { A=1 };
cout << typeid(typename std::underlying_type<Foo>::type).name();

...on Coliru and demangling via c++filt 将使用 g++clang++.[=22= 打印 "unsigned int" ]

即使您将 unsigned int 指定为 Foo 前向声明 的显式 基础类型 both compilers will complain.

enum Foo : unsigned int;
void bar(Foo);

enum Foo {A=1};

main.cpp:8:6: error: enumeration previously declared with fixed underlying type
enum Foo {A=1};
     ^
main.cpp:5:6: note: previous declaration is here
enum Foo : unsigned int;
     ^

这是因为前向声明和"real"enum声明都需要有相同的显式 底层类型,即使你设法 "guess" 编译器会为你选择什么。


tl;dr:如果前向声明和实际声明具有相同的 ,则只能前向声明 enum指定 底层类型。

从我今天的 gcc 版本开始,您必须定义两次确切的类型,不仅在前面的 声明 中,而且在 定义 :

enum Foo : int;

...

enum Foo : int {A=1};

这对我有用,编译器是 gcc 7.3.0。