Reputation: 3123
I'm working in C++11 and including an h file implemented in C++03. In the h file I'm including there's an enum Foo
defined. I want to declare a forward to it in code.h
and use it in 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) { }
This is the error I get when I compile (tested g++ 4.8.5 and 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;
I can fix this error if I change header.h to:
enum Foo : int {A=1};
But I don't own that header and can't change it. Taking the error at face value, it sounds like all I need to know is what type g++ uses for enums which don't specify underlying type, then use that type in my forward.
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";
}
Upvotes: 13
Views: 5858
Reputation: 387
As of my todays version of gcc, you have to define the exact type twice, not only in the forward declaration but as well in the definition:
enum Foo : int;
...
enum Foo : int {A=1};
This worked for me, compiler is gcc 7.3.0.
Upvotes: 2
Reputation: 93394
There doesn't seem to be any way of doing this, even if you specify the exact same underlying type that the compiler would have chosen for your C++03-style enum
.
Example: compiling the following code...
enum Foo { A=1 };
cout << typeid(typename std::underlying_type<Foo>::type).name();
...on Coliru and demangling via c++filt
will print "unsigned int"
both with g++ and clang++.
Even if you specify unsigned int
as the explicit underlying type of your Foo
forward declaration, 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;
^
This is because both the forward declaration and the "real" enum
declaration need to have the same explicit underlying type, even if you manage to "guess" what the compiler would have chosen for you.
tl;dr: you can only forward-declare an enum
if both the forward-declaration and the real declaration have the same explicitly specified underlying type.
Upvotes: 10
Reputation: 474506
You can only forward declare an enum if you give it a fixed underlying type in the forward declaration. Also, the definition of the enum must use the same fixed underlying type.
Your problem is that your enum definition in header.h
doesn't have an underlying type, but the later forward declaration has one. They both must have one.
Upvotes: 6