enum class的基于namespace的实现

摘要:
stringtx){type=tp;}stringText()常量{returntext;constToken&token){out<TokenType.Name(token.type())<“<inttype;”TEXT“};

之前实现的枚举类enum class虽然达到了当时期望的功能,但现在在用的时候出现了一些问题。比如新定义了一个Token的类,
定义如下,

class Token
{
public:
    Token(){}
    Token(int tp, string tx) {
        type = tp;
        text = tx;
    }
    int Type() const {
        return type;
    }
    string Text() const {
        return text;
    }
    friend ostream& operator << (ostream& out,const Token& token){
        out << "<" << TokenType.Name(token.Type()) << "," << token.Text() << ">" << endl;
    }
protected:
    int type;
    string text;
};

希望Token输出时,能够输出Token的类型的名字,这在之前的枚举类里面已经实现了,但是输出语句中TokenType.Name(type),直接使用了TokenType对象,如果type时ExprTokenType,那么就会出错,除非name是static的,在TokenType和ExprTokenType里面共用。如果这样做,name的初始化就会很麻烦,static成员需要在类外初始化,在构造函数中不能对它进行修改,那么,继承的ExprTokenType也不能在构造函数里面对它进行修改。这是一种解决方案,name在token对应的.cpp文件里面初始化,虽然目前只有main.cpp,其它的都是头文件,但是不得不增加.cpp了。这样貌似解决了,但Token里面输出的那一句话还是有问题啊。

另一种方案,使用namespace,将TokenType定义为namespace,扩展的时候也不需要继承,可以直接添加常量类型成员,而name的添加则可以放到对应Lexer的初始化里面。

// token.h
namespace TokenType{
    const static int _EOF = 0;
    const static int TEXT = 1;
    static vector<string> name = {"_EOF","TEXT"};
    const string Name(int x){
        return TokenType::name.at(x);    
    }
}

# exprtoken.h
#include "tname.h"
namespace TokenType{
    const static int NUMBER = 2;
    const static int OP = 3;

    static void SetNameExpr(){
        TokenType::name.push_back("NUMBER");
        //name.push_back("NUMBER");
        TokenType::name.push_back("OP");
    }
}

// main.cpp
int main()
{
    int type_a = TokenType::TEXT;
    string type_a_name = TokenType::Name(type_a);
    cout << "type_a:" << type_a_name << "," << type_a << endl;
    TokenType::SetNameExpr();
    int type_b = TokenType::NUMBER;
    string type_b_name = TokenType::Name(type_b);
    cout << "type_b:" << type_b_name << "," << type_b << endl;

    return 0;
}

本来应该很简单的问题,为什么现在搞得这么复杂呢?

免责声明:文章转载自《enum class的基于namespace的实现》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇TreeMap 的排序冲突吗管理并行SQL执行的进程下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

jquery应用图片拖拽排序

最近在研究Interface elements for jQuery(http://interface.eyecon.ro/),此插件封装了一些拖拽效果,并且使用非常简单,能轻松实现拖拽排序、购物车、博客首页排版等UI,所以模仿和讯的图片排序做了一个简单样例: 预览: 代码: <html><head><meta http-e...

WPF一步步实现完全无边框自定义Window(附源码)

   在我们设计一个软件的时候,有很多时候我们需要按照美工的设计来重新设计整个版面,这当然包括主窗体,因为WPF为我们提供了强大的模板的特性,这就为我们自定义各种空间提供了可能性,这篇博客主要用来介绍如何自定义自己的Window,在介绍整个写作思路之前,我们来看看最终的效果。     图一 自定义窗体主界面   这里面的核心就是重写Window的Templ...

怎么将swagger API导出为HTML或者PDF

文章目录 将swagger API导出为HTML或者PDF 什么是Asciidoc swagger2markup-maven-plugin asciidoctor-maven-plugin 使用命令行 PDF的中文展示 PDF中文主题在maven中的使用 将swagger API导出为HTML或者PDF 现在有很多项目都是使用的swagger...

[.Net 5.0] 5.终于搞定了输出路径

多个项目,编译后都存放到指定目录,比如c:output,原来很简单的 debug、release修改一下输出目录就ok。 现在不行了,他会帮您放置在c:output et5.0,如果您是wpf项目,他要求net5.0-windows,这时候他又保存到c:output et5.0-windows,好烦人。 参考了(如何更精准地设置C#/.NETCore项目的...

Unity中Instantiate物体失效问题

才开始学Unity,开始总是这样用Instantiate函数: GameObject temp = (GameObject)Instantiate(bulletSource, transform.position, transform.rotation); 然后该类中定义一个共有变量如下: public GameObject bulletSource;...

Visual Studio中你所不知道的智能感知

在Visual Studio中的智能感知,相信大家都用过。summary,param,returns这几个相信很多人都用过的吧。那么field,value等等这些呢。 首先在Visual Studio中支持的JavaScript智能感知有以下6种 summary 用于方法和主体内容 param 用于方法的参数 field 用于类的属性 va...