Reputation: 6695
I'm using this is_enum function to check if a variable is an enum or not. (See error below)
#include <boost/type_traits/is_enum.hpp>
#include <boost/static_assert.hpp>
template<typename T>
void is_enum(T)
{
BOOST_STATIC_ASSERT(boost::is_enum<T>::value == true);
}
int main()
{
char c = 'a';
is_enum(c);
return 0;
}
This gives me the following error:
-*- mode: compilation; default-directory: "/home/epronk/enums/" -*-
Compilation started at Thu Nov 10 21:20:05
g++ -I /home/epronk/src/boost_1_47_0/ q.cpp
q.cpp: In function ‘void is_enum(T) [with T = char]’:
q.cpp:13: instantiated from here
q.cpp:7: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>’
q.cpp:7: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>’
Compilation exited abnormally with code 1 at Thu Nov 10 21:20:05
(not sure why g++ (Debian 4.4.5-8) 4.4.5 give me the same error twice)
Is it possible to change this function so it becomes a warning?
For a char you can try to assign 256 to it which results in a overflow error.
edited
Some context: I want to find switch statements like this one.
#define switch(arg) \
is_enums(arg); \
switch(arg)
int main()
{
char c = Red;
switch(c)
{
case Banana: // No warning
break;
case Red:
break;
case Green:
break;
case Blue:
break;
}
return 0;
}
Upvotes: 5
Views: 2301
Reputation: 25140
EDIT: Try BOOST_STATIC_WARNING http://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/static_warning.html; the code below is my hand-hacked version of doing something similar.
Something like this:
#include <boost/type_traits/is_enum.hpp>
#include <boost/utility.hpp>
#include <boost/static_assert.hpp>
enum AB { A, B };
template<typename T>
typename boost::enable_if_c< boost::is_enum<T>::value,
void >::type is_enum(T) {
}
template<typename T>
typename boost::enable_if_c< !boost::is_enum<T>::value,
void >::type is_enum(T) {
int NOT_AN_ENUMERATION = 1;
}
int main()
{
char c = 'a';
is_enum(c);
is_enum(A);
is_enum(B);
return 0;
}
Will issue a warning about the unused variable if you get your compiler in the right state. With gcc and '-Wall', I get this sort of thing:
thing.cpp: In function 'typename boost::enable_if_c<(! boost::is_enum::value), void>::type is_enum(T) [with T = char]':
thing.cpp:21: instantiated from here
thing.cpp:15: warning: unused variable 'NOT_AN_ENUMERATION'
Upvotes: 6
Reputation: 1797
If you are using boost, you can use BOOST_STATIC_WARNING
defined in header <boost/serialization/static_warning.hpp>
. If that does not work on your compiler you can use BOOST_SERIALIZATION_BSW
defined in same header. Example code looks like BOOST_SERIALIZATION_BSW(std::is_enum<T>::value,1);
where the second parameter is an unique integer. The implementation is conceptually same as BOOST_STATIC_ASSERT except that it uses compiler specific warning such as "negative integer to unsigned conversion" for generation purpose.
Upvotes: 4
Reputation: 477100
The error is intentional, since you call a static assert, which means exactly "please trigger a compile-time error if the condition is false".
Your function is strangely named, though: It's not a conditional check whether the variable is an enum, but rather an assertion that it is. You should call it assert_that_var_is_enum_or_die()
or something meaningful like that.
A conditional should probably just be:
inline bool is_enum(T) { return boost::is_enum<T>::value; }
Upvotes: 4