The question in the title may sound trivial, so I better explain with some code what I want to do...
In C++11 I can do this:
#include <iostream>
namespace X {
enum class FOO { A,B };
}
template <typename T> void foo(T t) {
if (t == T::A) { std::cout << "A"; }
}
int main() {
foo(X::FOO::A);
}
The important point here is that the template foo
does not need to know in what namespace the enum is declared. I could as well call foo(Y::FOO::B)
(provided there is a enum class
called FOO
in namespace Y
having members A
and B
).
Now the question is: How to get the same with plain old enums (and only C++98 stuff)?
This works:
#include <iostream>
namespace X {
enum FOO { A,B };
}
template <typename T> void foo(T t) {
if (t == X::A) { std::cout << "A"; }
}
int main() {
foo(X::A);
}
but only because foo
knows in what namespace the enum is declared. And it wont work for a Y::FOO::B
! (In C++11 it also works if I replace the line with if (t == T::A) ...
, even with a plain enum
)
Is there a way to get this working in C++98/03 without refering to X
in the template explicitly?
For the sake of completeness, in C++98, this
template <typename T> void foo(T t) {
if (t == T::A) { std::cout << "A"; }
}
results in
error: ‘A’ is not a member of ‘X::FOO’
PS: I am not allowed to change the enum
and the template has to live in a different namespace than the enum
.
PPS: a simple if (t == 0)
would probably work, but thats something I would like to avoid
Inheritance Is Not Allowed for Enums.
An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.
Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.
To get all enum values as an array, pass the enum to the Object. values() method, e.g. const values = Object. values(StringEnum) .
Until C++11, there was no way to say "the enumerator name within this enumeration". That's why it was added to C++11, even to unscoped enumerations.
To add to Nicol Bolas' answer, you can kind of hack your way to a solution using ADL:
namespace X {
enum FOO { A,B };
bool IsA(FOO t)
{
return t == A;
}
}
template <typename T> void foo(T t) {
if (IsA(t)) { std::cout << "A\n"; }
else{std::cout << "not A\n";}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With