Are enums the canonical way to implement bit flags?

后端 未结 3 2035
死守一世寂寞
死守一世寂寞 2021-02-19 04:30

Currently I\'m using enums to represent a state in a little game experiment. I declare them like so:

namespace State {
  enum Value {
    MoveUp = 1 << 0,          


        
3条回答
  •  后悔当初
    2021-02-19 04:46

    The STL contains std::bitset, which you can use for precisely such a case.

    Here is just enough code to illustrate the concept:

    #include 
    #include 
    
    class State{
    public:
        //Observer
        std::string ToString() const { return state_.to_string();};
        //Getters
        bool MoveUp()    const{ return state_[0];}; 
        bool MoveDown()  const{ return state_[1];}; 
        bool MoveLeft()  const{ return state_[2];}; 
        bool MoveRight() const{ return state_[3];}; 
        bool Still()     const{ return state_[4];}; 
        bool Jump()      const{ return state_[5];}; 
        //Setters
        void MoveUp(bool on)    {state_[0] = on;}
        void MoveDown(bool on)  {state_[1] = on;}
        void MoveLeft(bool on)  {state_[2] = on;}
        void MoveRight(bool on) {state_[3] = on;}
        void Still(bool on)     {state_[4] = on;}
        void Jump(bool on)      {state_[5] = on;}
    private:
        std::bitset<6> state_;
    };
    
    
    int main() {
        State s;
        auto report = [&s](std::string const& msg){
            std::cout<

    Here's it working: http://ideone.com/XLsj4f

    The interesting thing about this is that you get std::hash support for free, which is typically one of the things you would need when using state inside various data structures.

    EDIT: There is one limitation to std::bitset and that is the fact that you need to know the maximum number of bits in your bitset at compile time. However, that is the same case with enums anyway.

    However, if you don't know the size of your bitset at compile time, you can use boost::dynamic_bitset, which according to this paper (see page 5) is actually really fast. Finally, according to Herb Sutter, std::bitset was designed to be used in cases you would normally want to use std::vector.

    That said, there really is no substitute for real world tests. So if you really want to know, profile. That will give you performance numbers for a context that you care about.

    I should also mention that std::bitset has an advantage that enum does not - there is no upper limit on the number of bits you can use. So std::bitset<1000> is perfectly valid.

提交回复
热议问题