有没有办法在没有命名空间的情况下在 C++ 中嵌套枚举?

Is there a way to nest enums in c++ without namespace?

我正在为给定的 AST 实现字节码生成器。在创建表达式 class 时,我注意到一元运算符和二元运算符之间的区别。为简单起见,unum 是首选解决方案,因此我以这种方式嵌套了 enuns:

enum EXP_TYPE
{
    enum BINARY
    {
        PLUS,
        MINUS,
        MULTIPLY,
        DIV,
        ...
    };
    enum UNARY
    {
        PLUS,
        MINUS,
        POINTER,
        INC,
        ...
    };
};

当然,这段代码会抛出警告,告知这是不允许的。所以我在 Whosebug 和其他来源上搜索了一下,找到了使用 namespace 而不是 enum 来声明 EXP_TYPE 的解决方案。但是现在的问题是在表达式 class:

中使用
class expression
{
    expression *right_exp;
    expression *left_exp;
    EXP_TYPE type;
    ...
};

不再允许使用 EXP_TYPE,因为它是 namespace 而不是 enum 类型。我打算做的是一个通用的 enum 声明,它可以用作 class 中的属性,在这里通用意味着它可以是 BINARYUNARY,即属性 EXP_TYPE type 可以有如下赋值和比较:

 expression exp1;
 exp1.type = EXP_TYPE::BINARY::PLUS;
 exp1.type = EXP_TYPE::UNARY::PLUS;

有没有办法在不使用 namespace 的情况下创建这些简单的泛型类型,或者不需要为一元和二元运算符创建 class 层次结构?

不,您不能在枚举内部创建作用域。

相反,使用更长的名称(例如 EXP_TYPE::BINARY_PLUS)对您的枚举进行分类。

我把这当成一个谜,想知道我能达到 OP 要求的程度。

这是我得到的(尽管我必须承认它看起来有点吓人):

#include <cassert>
#include <iostream>

struct ExpType {
  struct Unary {
    enum {
      Plus, Minus, Pointer, Inc,
      N
    };
  };
  struct Binary {
    enum {
      Plus = Unary::N, Minus, Multiply, Div,
      N
    };
  };
  enum {
    N = Binary::N
  };

  int value;

  ExpType(int value = 0): value((assert(value >= 0 && value < N), value)) { }
  ~ExpType() = default;
  ExpType(const ExpType&) = default;
  ExpType& operator=(const ExpType&) = default;

  operator int () { return value; }
};

int main()
{
  for (int i = 0; i < ExpType::N; ++i) {
    ExpType expType = i;
    switch (expType) {
#define CASE(TYPE) case TYPE: std::cout << #TYPE "\n"; break
      CASE(ExpType::Unary::Plus);
      CASE(ExpType::Unary::Minus);
      CASE(ExpType::Unary::Pointer);
      CASE(ExpType::Unary::Inc);
      CASE(ExpType::Binary::Plus);
      CASE(ExpType::Binary::Minus);
      CASE(ExpType::Binary::Multiply);
      CASE(ExpType::Binary::Div);
#undef CASE
      default: std::cout << "Unknown expression type!\n";
    }
  }
}

输出:

ExpType::Unary::Plus
ExpType::Unary::Minus
ExpType::Unary::Pointer
ExpType::Unary::Inc
ExpType::Binary::Plus
ExpType::Binary::Minus
ExpType::Binary::Multiply
ExpType::Binary::Div

Live Demo on coliru

但是,我必须承认,我个人肯定更喜欢 中推荐的内容。