2

I have an ATL COM service and in the .IDL file, I've declared an enum like so:

In Gourmet.idl

typedef enum Food
{
    Chocolate = 0,
    Doughnut,
    HotDog
} Food;

A header file is automatically generated, creating Gourmet_i.h.

In another .CPP file (let's just call it Decadence.cpp) of the same ATL COM project, I #include Gourmet_i.h. I've implemented a class in this .CPP and it's under the namespace 'Chocolate'.

For example in Decadence.cpp:

#include "Gourmet_i.h"

namespace Chocolate {

// Constructor
void Decadence::Decadence() {}

// ... and so on

} // namespace Chocolate

When compiled I get the following error about Gourmet_i.h:

error C2365: 'Chocolate': redefinition; previous definition was 'namespace'

I see this occurs because the enum for the IDL is defined in the global namespace, but is it possible to contain this definition -- so it doesn't pollute the global namespace -- and I wouldn't have this conflict?

zakinster
  • 10,508
  • 1
  • 41
  • 52
ykay
  • 1,877
  • 19
  • 24
  • What is the point of that `typedef`? This isn't C. In C++, tag lookup is performed automatically without having to specify `enum` or `struct`. – underscore_d May 13 '16 at 22:36

2 Answers2

4

Short of renaming the namespace or enum member about the only solution for this is to wrap the contents of the generated header file in a namespace. This is not without pitfalls and depending on how the contents of your MIDL file it may eventually cause a few headaches. The cleanest way that I can see would be to create a proxy header file that declares the namespace then includes the MIDL generated header file.

Gourmet.h

namespace MIDLStuff
{
    #include "Gourmet_i.h"
}
Captain Obvlious
  • 19,754
  • 5
  • 44
  • 74
  • this seems to be the cleanest way to do it. worked for me. on a side note, I'm going to start staying away from declaring enums in COM interfaces. – ykay Apr 19 '13 at 21:27
  • 1
    @ykay: whether you declare an enum in IDL or not should not be driven by this problem. If you define a method that uses the enum, you need the enum in the interface. Some people choose to name the enum members `fdChocolate`, `fdDoughnut`, etc. That might work for you as an alternative. The fact that enum members are unscoped is a quirk of C (and inherited by C++), not IDL's fault. – Euro Micelli Apr 20 '13 at 14:23
1

If you are using C++11 you can use Scoped Enumeration by including class:

typedef enum class Food
{
    Chocolate = 0,
    Doughnut,
    HotDog
} Food;

Now you need to write Food::Chocolate when using the value.