【问题标题】:Flexible enums in C++C++ 中的灵活枚举
【发布时间】:2015-09-02 15:09:07
【问题描述】:

我如何组织枚举,以便每个枚举条目都可以有参数,就像我在 Haxe 中可以做的那样,例如:

enum GraphicAct {
  ClearScreen; 
  MoveTo(x:Float, y:Float);
  LineTo(x:Float, y:Float);
  FillColor(color:Int);
  EndFill;
}

function main(){
  var actions:Array<GraphicAct>;
  actions.push(ClearScreen);
  actions.push(FillColor(0xaaffff));
  actions.push(MoveTo(100, 100));
  actions.push(LineTo(200, 100));
  actions.push(LineTo(100, 200));
  actions.push(EndFill);


  for(act in actions){
    switch(act){
       case ClearScreen: // do clear screen here...
       case MoveTo(x, y): // move position
       case LineTo(x, y): // move position
    }
  }
}

据我所知,C++ 仅支持不带参数的枚举条目,例如“ClearScreen”和“EndFill”,但在这种情况下,我如何在 C++ 中组织命令序列,就像我在示例中使用图形命令所做的那样?

【问题讨论】:

  • 为什么要将它作为枚举?你可以通过 GraphicsAct 基类得到你想要的,然后使用多态

标签: c++ enums enumeration


【解决方案1】:

您可以使用unionenum,例如:

enum class EGraphicActType
{
    ClearScreen, MoveTo, LineTo, FillColorData, EnfFillData
};

struct ClearScreenData {};
struct MoveToData { float x; float y;};
struct LineToData { float x; float y;};
struct FillColorData { Int color;};
struct EnfFillData {};

struct GraphicAct {
    EGraphicActType type;
    union
    {
        ClearScreenData clearScreenData;
        MoveToData moveToData;
        LineToData lineToData;
        FillColorData fillColorData;
        EnfFillData endFillData;
    } data;
};

如果您有权使用 boost,则可以使用 boost::variant

【讨论】:

    【解决方案2】:

    为此,c++ 提供了结构和类。 C++ 枚举是一组预定义值中的一个特定值。

    编辑:这是一个可能的解决方案的示例

    class Action {
     public:
      doAction();
    }
    
    class ClearScreen : public class Action {
     public:
      doAction() {
       // do something
      }
    }
    
    class MoveTo : public class Action {
     public:
      int x, y;
    
      doAction() {
       // do something
      }
    }
    
    // Etc for other things you want to do;
    
    int main() {
      std::vector<Action> Actions;
      ClearScreen clr;
      Actions.push_back(clr);
      MoveTo move;
      move.x = 100;
      move.y = 100;
      Actions.push_back(move);
    
     for (Action a:Actions) {
       a.doAction();
     }
    }
    

    对不起,我只是在路上,无法检查代码是否真的有效,但我认为你应该明白了。

    【讨论】:

    • 这不能回答问题或提供解决方案。这应该是评论而不是答案。
    • 正确。我添加了示例
    猜你喜欢
    • 2010-11-26
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多