Count on enum C++ automatic

后端 未结 5 1893
北荒
北荒 2020-12-10 09:27

I\'ve come to a pattern when writing enums in C++. It is like this:

class Player
{
public:
    class State
    {
    public:
        typedef enum
        {
          


        
5条回答
  •  一整个雨季
    2020-12-10 09:54

    Must the type of PossibleValues be an enum? If you just need something that behaves like an enum, you can do the following:

    #include 
    
    #include 
    #include 
    
    
    template 
    class Iterable_Strong_Enum
    {
    private:
      struct T_Ptr_Less : public std::binary_function
      {
        bool operator()(T const * x, T const * y) const
        {
          return x->get_representation() < y->get_representation();
        }
      };
    
    public:
      typedef std::set instances_list;
      typedef typename instances_list::const_iterator const_iterator;
    
      Representation const & get_representation() const { return _value; }
    
      static Representation const & min() { return (*_instances.begin())->_value; }
    
      static Representation const & max() { return (*_instances.rbegin())->_value; }
    
      static T const * corresponding_enum(Representation const & value)
      {
        const_iterator it = std::find_if(_instances.begin(), _instances.end(), [&](T const * e) -> bool
        {
          return e->get_representation() == value;
        });
        if (it != _instances.end())
        {
          return *it;
        }
        else
        {
          return nullptr;
        }
      }
    
      bool operator==(T const & other) const { return _value == other._value; }
      bool operator!=(T const & other) const { return _value != other._value; }
      bool operator< (T const & other) const { return _value <  other._value; }
      bool operator<=(T const & other) const { return _value <= other._value; }
      bool operator> (T const & other) const { return _value >  other._value; }
      bool operator>=(T const & other) const { return _value >= other._value; }
    
      static bool is_valid_value(Representation const & value) { return corresponding_enum(value) != nullptr; }
    
      static typename instances_list::size_type size() { return _instances.size(); }
    
      static const_iterator begin() { return _instances.begin(); }
    
      static const_iterator end() { return _instances.end(); }
    
    protected:
      explicit Iterable_Strong_Enum(Representation const & value);
    
    private:
      Representation _value;
    
      static instances_list _instances;
    };
    
    template 
    Iterable_Strong_Enum::Iterable_Strong_Enum(Representation const & value)
    : _value(value)
    {
      _instances.insert(static_cast(this));
    }
    
    class PossibleValues : public Iterable_Strong_Enum
    {
    public:
      static const PossibleValues Stopped;
      static const PossibleValues Playing;
      static const PossibleValues Pause;
    protected:
    private:
      explicit PossibleValues(int value);
    };
    
    PossibleValues::PossibleValues(int value) : Iterable_Strong_Enum(value) { }
    
    // you need to call that explicitly
    Iterable_Strong_Enum::instances_list Iterable_Strong_Enum::_instances;
    
    const PossibleValues PossibleValues::Stopped(0);
    const PossibleValues PossibleValues::Playing(1);
    const PossibleValues PossibleValues::Pause(2);
    
    void stackoverflow()
    {
      std::cout << "There are " << PossibleValues::size() << " different possible values with representation: " << std::endl;
      for (auto pv = PossibleValues::begin(); pv != PossibleValues::end(); ++pv)
      {
        PossibleValues possible_value = **pv;
        std::cout << possible_value.get_representation() << std::endl;
      }
    }
    

    I'm kinda torn about that solution. On the one hand, its pretty general and on the other hand its a big hammer for a small problem.

提交回复
热议问题