有没有办法在没有命名空间的情况下在 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 中的属性,在这里通用意味着它可以是 BINARY 或 UNARY,即属性 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
但是,我必须承认,我个人肯定更喜欢 中推荐的内容。
我正在为给定的 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 中的属性,在这里通用意味着它可以是 BINARY 或 UNARY,即属性 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
但是,我必须承认,我个人肯定更喜欢