创建C ++枚举和依赖数据结构时,如何避免重复? [英] How can I avoid repeating myself when creating a C++ enum and a dependent data structure?

查看:144
本文介绍了创建C ++枚举和依赖数据结构时,如何避免重复?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

枚举到字符串:如果无效/未找到则返回枚举整数值


简而言之,我的(工作)定义代码是这样的:

 枚举小工具
{
首先,
二,
};

const char * gadget_debug_names [] = {
First,
Second,
//注意:字符串与枚举令牌相同,但奖金点如果
//他们可以选择不同的值
};

但是,信息容易出现在多个不同的地方,必须手动维护。 (在某些情况下,在代码库中,我正在使用这两个或更多的地方甚至目前不在同一个文件中)。所以只要命名这些东西就会很好。



现在我们可以通过代码生成和声明性数据文件来实现,但是如果有更好的方法,我不希望为现有的构建过程添加另一个步骤。有一些看起来像

  DEFINE_GADGET(First)
DEFINE_GADGET(Second)
(如果需要,可以选择启动/停止宏)但是,由于宏只是纯文本替换,所以我不能没有任何方式让预处理器在写出枚举定义时记住令牌。



我以为也可能通过元编程,但是我对如何做到这一点感到失落。我在那里看到的所有例子都涉及递归构建数据结构。我可以看到我如何以这种方式构建字符串数组,但我不知道如何传递一个令牌名称,或者如何构建一个枚举。 (当然,使用元编程只是构建一个数组的字符串将是非常可笑的。)



有没有办法让我在这里保持DRY,而不使用代码生成?

解决方案

有一个旧的预处理技巧:



Gadget.data



  DEFINE_GADGET(第一个)
DEFINE_GADGET(Second)



小工具。 * *



  #define QUOTE_VAL(X)#X 

枚举小工具
{
#define DEFINE_GADGET(X)X,
#includeGadget.data
#undef DEFINE_GADGET(X)
};

const char * gadget_debug_names [] = {
#define DEFINE_GADGET(X)QUOTE_VAL(X),
#includeGadget.data
#undef DEFINE_GADGET X)
};


Possible Duplicate:
Enum to string : return the enum integer value if invalid / not found

In brief, the (working) definition code that I have is something like this:

enum Gadget
{
    First,
    Second,
}; 

const char* gadget_debug_names[] = {
    "First",
    "Second",
    // note: strings are same as enum tokens here, but bonus points if
    //       they can optionally be given different values
};

However, it's error prone that the information is in multiple separate places that have to be maintained manually. (And in some cases in the code base I'm working with those two--or more--places aren't even currently in the same file.) So it would be really nice to just name those things once.

Now we could do this with code generation and a declarative data file, but I'd prefer not to add another step to the existing build process if there's a better way to do this. It would be perfect to have something that looks like

DEFINE_GADGET(First)
DEFINE_GADGET(Second)

(optionally with start/stop macros if needed) But, since macros are just plain text substitution, I can't figure out any way to have the preprocessor "remember" the tokens while it's writing out the enum definition.

I've thought that this might also be possible through meta-programming, but I'm at a loss on how to do it. All of the examples I've seen there involve recursively building a data structure. I can see how I might build the array of strings that way, but I'm not sure how I could pass in a token name, or how to build an enum. (And of course using metaprogramming just to build an array of strings would be pretty ridiculous.)

Is there any way for me to keep DRY here, without using code generation?

解决方案

There is an old pre-processor trick for this:

Gadget.data

DEFINE_GADGET(First)
DEFINE_GADGET(Second)

Gadget.**

#define QUOTE_VAL(X)  #X

enum Gadget
{
#define DEFINE_GADGET(X)   X,
#include "Gadget.data"
#undef DEFINE_GADGET(X)
}; 

const char* gadget_debug_names[] = {
#define DEFINE_GADGET(X)   QUOTE_VAL(X),
#include "Gadget.data"
#undef DEFINE_GADGET(X)
};

这篇关于创建C ++枚举和依赖数据结构时,如何避免重复?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆