我正在使用此is_enum函数来检查变量是否为枚举。 (见下面的错误)
#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;
}
这给了我以下错误:
-*- 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
(不确定为什么g ++(Debian 4.4.5-8)4.4.5两次给我同样的错误)
是否可以更改此功能以使其成为警告?
对于char,您可以尝试为其分配256,这会导致溢出错误。
编辑
某些上下文:我想找到像这样的switch语句。
#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;
}
答案 0 :(得分:6)
编辑:尝试BOOST_STATIC_WARNING http://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/static_warning.html;下面的代码是我的手工黑客版本做类似的事情。
这样的事情:
#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;
}
如果编译器处于正确状态,将发出有关未使用变量的警告。使用gcc和'-Wall',我得到了这样的东西:
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'
答案 1 :(得分:4)
错误是有意的,因为你调用静态断言,这意味着“如果条件为假,请触发编译时错误”。
你的函数命名奇怪:它不是一个条件检查变量是否是一个枚举,而是一个断言 它。您应该将其称为assert_that_var_is_enum_or_die()
或类似的有意义的内容。
条件应该只是:
inline bool is_enum(T) { return boost::is_enum<T>::value; }
答案 2 :(得分:4)
如果您使用的是提升,则可以使用标头BOOST_STATIC_WARNING
中定义的<boost/serialization/static_warning.hpp>
。如果这对您的编译器不起作用,您可以使用在同一标头中定义的BOOST_SERIALIZATION_BSW
。示例代码看起来像BOOST_SERIALIZATION_BSW(std::is_enum<T>::value,1);
,其中第二个参数是唯一的整数。该实现在概念上与BOOST_STATIC_ASSERT相同,不同之处在于它使用编译器特定的警告,例如“负整数到无符号转换”用于生成目的。