I've had the same issue in the past, and this is how I've fixed it.
I wanted to be able to switch the implementation of a library at compile time.
One of the lib was using code like this:
namespace Lib1
{
enum LibEnum { One, Two, Three };
[...]
void someFunc(LibEnum val);
}
In my code, I wanted to hide the library implementation from the user experience (so a user of my code should never see what lib I'm using internally):
Solution 1:
namespace MyCode
{
// Example to avoid copying a function from Lib1 here
typedef Lib1::someFunc aFunctionImUsing;
// This doesn't work
// typedef LibEnum MyEnum;
// As such code doesn't compile:
// aFunctionImUsing(One); // Error unknown identifier One
// But this did:
struct Type
{
enum MyType { One = Lib1::One, Two = Lib1::Two, Three = Lib1::Three };
}
static inline Lib1::LibEnum as(Type::MyType t) { return (Lib1::LibEnum)t; }
// Now code like this compiles:
aFunctionImUsing(as(Type::One));
// This one doesn't:
// aFunctionImUsing(Type::One); // Can't convert from Type::MyType to Lib1::LibEnum
[...]
}
Solution 2:
namespace MyCode
{
struct Type
{
enum MyType { One = Lib1::One, Two = Lib1::Two, Three = Lib1::Three };
}
// If you don't care about polluting your namespace with numerous wrapper
// you can write this instead of typedef someFunc:
static inline void myFunc(Type::MyType t) { return Lib1::someFunc((Lib1::LibEnum)t); }
// This one does:
myFunc(Type::One);
[...]
}
They are 2 issues with the code fragment above. The first issue is that you must copy & paste the enum inside your namespace, (but with a simple regular expression in find&replace, you're done).
The second issue is that your user will have to use the "as" method, which means that it's not straightforward, or you have to wrap the method/function using the second solution.
Anyway, as it's not possible to inject an enum across namespace, this solution is the best you can do. Notice that your code user don't even know you're using the Lib1 library in the example code.