I'm trying to implement std::is_enum
. Here is my code so far:
template<typename T>
struct is_enum {
static bool value;
};
template<typename T>
bool is_enum<T>::value = false;
template<enum E>
struct is_enum {
static bool value;
};
template<enum E>
bool is_enum<E>::value = true;
This code causes error. More precisely:
g++ -std=c++0x -Wall -o "enum2" "enum2.cpp" (in directory: /home/aristophanes/Desktop/C++)
Compilation failed.
enum2.cpp:11:15: error: use of enum ‘E’ without previous declaration
enum2.cpp:3:10: error: template parameter ‘class T’
enum2.cpp:12:8: error: redeclared here as ‘int E’
enum2.cpp:16:15: error: use of enum ‘E’ without previous declaration
enum2.cpp:17:14: error: ‘E’ was not declared in this scope
enum2.cpp:17:15: error: template argument 1 is invalid
enum2.cpp:17:18: error: template declaration of ‘bool value’
Can anyone explain to me where I make a mistake? It is mine or the compiler's fault? Thanks in advance.
Edit: if it is completely wrong, then how can I correct it?
Note: I'm using g++ -o <file> <file>.cpp
Best Answer
The best way to implement this is to use compiler magic, and I believe most implementations do this.
For example, here's libc++'s implementation for gcc >= 4.3 and any compiler that
__has_feature(is_enum)
1For all other compilers libc++ does:
Some of those other type traits still require compiler magic.2 E.g.
is_union
. However, that condition can be rewritten such that it doesn't need compiler magic. This can be done by replacing the seperate checks for unions and classes with a single check for both, as Johannes Schaub points out.1. So far as I know only clang implements
__has_feature
, unfortunately.2. It's interesting that libc++ does have a version of
is_union<T>
andis_class<T>
that do not use compiler intrinsics, but as a result they provide erroneous results for union types. But their erroneous results are complementary so libc++'s fallback implementation ofis_enum<T>
provides accurate results.