Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
195 views
in Technique[技术] by (71.8m points)

c++ - How can I use an enum class in a boolean context?

I have some generic code that works with flags specified using C++11 enum class types. At one step, I'd like to know if any of the bits in the flag are set. Currently, I'm using the code:

if (flags != static_cast<E>(0)) // Works, but ugly.

I could also force users to specify a particular name for an all-zero field, which is more readable but imposes my naming conventions on anyone using it:

if (flags != E::none) // Works, if you manually define none = 0.

But neither of these reads as nicely as the traditional:

if (flags) // Doesn't work with class enums.

Is it possible to specify a custom function to evaluate a class enum in a boolean context?

question from:https://stackoverflow.com/questions/9874960/how-can-i-use-an-enum-class-in-a-boolean-context

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Is it possible to specify a custom function to evaluate a class enum in a boolean context?

Yes, but not automatically. Manually calling a function is still more elegant than the other alternatives presented.

Simply pick a nice function name, such as any, and implement it. Overload resolution will make sure your function plays well with all others.

bool any( E arg )
    { return arg != E::none; }

...

if ( any( flags ) ) {
    ...

Looks nice enough to me.


Update: if you want this to apply to several enumeration types, it can be templated:

template< typename enum_type > // Declare traits type
struct enum_traits {}; // Don't need to declare all possible traits

template<>
struct enum_traits< E > { // Specify traits for "E"
    static constexpr bool has_any = true; // Only need to specify true traits
};

template< typename enum_type > // SFINAE makes function contingent on trait
typename std::enable_if< enum_traits< enum_type >::has_any,
    bool >::type
any( enum_type e )
    { return e != enum_type::none; }

I've been using this sort of mechanism for other things and never encountered any side effects or issues :v) .

You could skip the trait and set the SFINAE condition to something like enum_type::none == enum_type::none, to merely check for the presence of none and the equality operator, but that would be less explicit and safe.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...