首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从C++宏中创建字符串列表和枚举列表

从C++宏中创建字符串列表和枚举列表
EN

Stack Overflow用户
提问于 2011-04-03 22:43:09
回答 6查看 29.8K关注 0票数 24

为了使我的代码更短,更容易修改,我想要替换如下内容

代码语言:javascript
复制
enum{ E_AAA, E_BBB, E_CCC };
static const char *strings{"AAA", "BBB", "CCC" };

使用宏,如INIT(AAA,BBB,CCC);但当我尝试使用变量参数和字符串化宏时,我得到一个错误,因为参数没有声明。

你知道该怎么做吗?

EN

回答 6

Stack Overflow用户

发布于 2011-12-02 06:35:13

你可以使用一些微距魔法来完成这项工作:

代码语言:javascript
复制
#define FRUITS \
    etype(Unknown), \
    etype(Apple),   \
    etype(Orange),  \
    etype(Banana),  \
    etype(Apricot), \
    etype(Mango)

#define etype(x) F_##x

typedef enum { FRUITS } Fruit;

#undef etype
#define etype(x) #x

static const char *strFruit[] = { FRUITS };

下面是一个测试程序:

代码语言:javascript
复制
#include <iostream>
#include <exception>
#include <vector>

#define FRUITS \
    etype(Unknown), \
    etype(Apple),   \
    etype(Orange),  \
    etype(Banana),  \
    etype(Apricot), \
    etype(Mango)

#define etype(x) F_##x

typedef enum { FRUITS } Fruit;

#undef etype
#define etype(x) #x

static const char *strFruit[] = { FRUITS };

const char *enum2str (Fruit f)
{
    return strFruit[static_cast<int>(f)];
}

Fruit str2enum (const char *f)
{
    const int n = sizeof(strFruit) / sizeof(strFruit[0]);
    for (int i = 0; i < n; ++i)
    {
        if (strcmp(strFruit[i], f) == 0)
            return (Fruit) i;
    }
    return F_Unknown;
}

int main (int argc, char *argv[])
{
    std::cout << "I like " << enum2str(F_Mango) << std::endl;
    std::cout << "I do not like " << enum2str(F_Banana) << std::endl;
    std::vector<char *> v;
    v.push_back("Apple");
    v.push_back("Mango");
    v.push_back("Tomato");
    for (int i = 0; i < v.size(); ++i)
    {
        const Fruit f = str2enum(v[i]);
        if (f == F_Unknown)
            std::cout << "Is " << v[i] << " a fruit?" << std::endl;
        else
            std::cout << v[i] << " is a fruit" << std::endl;
    }
    return 0;
}

它输出:

代码语言:javascript
复制
I like Mango
I do not like Banana
Apple is a fruit
Mango is a fruit
Is Tomato a fruit?
票数 18
EN

Stack Overflow用户

发布于 2013-07-04 16:51:09

以下是我的解决方案:

代码语言:javascript
复制
#define FRUITS(fruit) \
  fruit(Apple)        \
  fruit(Orange)       \
  fruit(Banana)       

#define CREATE_ENUM(name) \
  F_##name,

#define CREATE_STRINGS(name) \
  #name,

诀窍是“水果”是宏观“水果”的一个参数,它将被你传递给的任何东西所取代。例如:

代码语言:javascript
复制
FRUITS(CREATE_ENUM)

将扩展到以下内容:

代码语言:javascript
复制
F_Apple, F_Orange, F_Banana, 

让我们创建枚举和字符串数组:

代码语言:javascript
复制
enum fruit {
  FRUITS(CREATE_ENUM)
};

const char* fruit_names[] = {
  FRUITS(CREATE_STRINGS)
};
票数 15
EN

Stack Overflow用户

发布于 2011-04-03 23:08:52

这是一个使用Boost.Preprocessor的解决方案:

代码语言:javascript
复制
#include <boost/preprocessor.hpp>

#define DEFINE_ENUM_DECL_VAL(r, name, val) BOOST_PP_CAT(name, BOOST_PP_CAT(_, val))
#define DEFINE_ENUM_VAL_STR(r, name, val) BOOST_PP_STRINGIZE(val)
#define DEFINE_ENUM(name, val_seq)                                                 \
  enum name {                                                                      \
    BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(DEFINE_ENUM_DECL_VAL, name, val_seq)) \
  };                                                                               \
  static const char* BOOST_PP_CAT(name, _strings[] = ) {                           \
    BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(DEFINE_ENUM_VAL_STR, name, val_seq)) \
  };

DEFINE_ENUM(E, (AAA)(BBB)(CCC))

(AAA)(BBB)(CCC)是树元素AAA、BBB和CCC的Boost.Preprocessor序列;宏将枚举名称附加到它的模态:

代码语言:javascript
复制
enum E { E_AAA, E_BBB, E_CCC };
static const char* E_strings[] = { "AAA", "BBB", "CCC" };
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5530248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档