C++ 11 Enum forward导致"底层类型不匹配"

yto*_*ano 8 c++ gcc g++ forward-declaration c++11

我在C++ 11中工作,包括用C++ 03实现的h文件.在h文件中我包含了枚举的枚举Foo.我想申报一个转发code.h并将其用于code.cpp:

header.h:

enum Foo {A=1};
Run Code Online (Sandbox Code Playgroud)

code.h:

enum Foo : int; // also tried : unsigned int, long, short, unsigned short, char, unsigned char
void bar(Foo foo);
Run Code Online (Sandbox Code Playgroud)

code.cpp:

#include header.h
void bar(Foo foo) { }
Run Code Online (Sandbox Code Playgroud)

这是我编译时得到的错误(测试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;
Run Code Online (Sandbox Code Playgroud)

如果我将header.h更改为:我可以修复此错误:

enum Foo : int {A=1};
Run Code Online (Sandbox Code Playgroud)

但我不拥有那个标题,也无法改变它.以面值表示错误,听起来我需要知道的是g ++使用哪种类型的枚举而不指定底层类型,然后在我的转发中使用该类型.

即使这个简单的例子也行不通:

#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";
}
Run Code Online (Sandbox Code Playgroud)

Vit*_*meo 7

即使您指定编译器为C++ 03样式选择的完全相同的基础类型,似乎也没有任何方法可以执行此操作enum.

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

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

... 在Coliru和demangling viac++filt上将"unsigned int"使用g ++clang ++打印.

即使你指定unsigned int的明确基础类型您的Foo 向前声明,两种编译器会抱怨.

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

enum Foo {A=1};
Run Code Online (Sandbox Code Playgroud)

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;
     ^
Run Code Online (Sandbox Code Playgroud)

这是因为前向声明和"真实" enum声明都需要具有相同的显式底层类型,即使您设法"猜测"编译器将为您选择的内容.


tl; dr:enum如果前向声明和真实声明都具有相同的明确指定的基础类型,则只能转发声明.


Nic*_*las 5

如果在前向声明中为其提供固定的基础类型,则只能前向声明枚举。此外,枚举的定义必须使用相同的固定基础类型。

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

  • @ytoledano:您要求编译器确定 * 尚未定义 * 的枚举的隐式基础类型。这不可能*。编译器没有看到 `Foo` 的定义,因此 `std::underlying_type&lt;Foo&gt;::type` 不是合法的语法。隐式基础类型基于 `Foo` 的定义,它位于您没有包含的标头中(如果您包含了,则没有必要向前声明枚举)。 (4认同)