c++ - C++ 中的另一个静态数组初始化

标签 c++ arrays static initialization

我在 C++ 中有以下代码(C++11 可用)

typedef enum
{ 
   APPLE,
   ORANGE,
   LAST,
} fruits_t;

template <typename T, size_t size> char (&ArraySizeHelper( T (&)[size]))[size];
#define arraysize(pArray) sizeof(ArraySizeHelper(pArray))

static const char *LOOKUP_TABLE[]
{
   "apple",  // APPLE
   "orange", // ORANGE
};
// Fail the compilation if the lookup table is missing anything
static_assert(arraysize(LOOKUP_TABLE) == LAST, "Update the lookup table");

我希望能够在不更改 LOOKUP_TABLE 中的初始化列表的情况下更改枚举中的顺序。

我读过这个Initialization of a normal array with one default value模板几乎是我所需要的,但不完全是。我在元编程上苦苦挣扎了半天,仍然不知道该怎么做。

代码中的实际枚举从零开始,包含 20-30 个条目。我考虑过哈希表——哈希函数很简单,但初始化问题仍然存在。我在代码中有很多 - 5+ - 像这样的查找表。值得奋斗吗?

附言在围绕 switch 构造给出几个答案之后,让我展示一段真实的代码。这只是一个例子。

typedef enum
{
    EVENTS_STATISTICS_COLLECTOR_POOL_TIMEOUT            ,
    EVENTS_STATISTICS_COLLECTOR_POOL_FAILED             ,
    EVENTS_STATISTICS_COLLECTOR_SENT_TO_PIPELINE        ,

    // 50 entries like this 
    EVENTS_STATISITCS_LAST                              ,
} events_statistics_t;

uint64_t events_statistics[EVENTS_STATISITCS_LAST];
const char *event_statistics_names[] = {
    "collector_pool_timeout         ",
    "collector_pool_failed          ",
    "collector_sent_to_pipeline     ",
    // and so on ...
};

static inline void events_statistics_bump_counter(events_statistics_t counter)
{
    events_statistics[counter]++;
}

// The actual function is a generic one which prints arbitrary pairs
// But this one gives an idea
void print_statistics()
{
    int col = 0;
    static const int COLUMNS = 3;
    printf("\n");
    for (int i = 0;i < EVENTS_STATISITCS_LAST;i++)
    {
        printf("%-30s %9lu", event_statistics_names[i], events_statistics[i]);
        col++;
        if ((col % COLUMNS) == 0)
            printf("\n");
        else
            printf("%4s", "");
    }
    if ((col % COLUMNS) != 0)
        printf("\n");
}

P.S.2 上一个P.S想说的是“开关”给了编译器太多的自由。我想确保查找是一个简单的表,而不是一些双索引数组或 if/else 分支

P.S.3 这是另一个初始化数组的例子。该数组包含钩子(Hook),调用正确的函数非常重要。

typedef struct
{
    const int id;
    const events_process_t processor;
    uint64_t counter;
} events_process_table_t;

static events_process_table_t events_processors[EVENT_ID_LAST] =
{
        {EVENT_ID_OPEN          , (events_process_t)events_process_open             },
        {EVENT_ID_OPENAT        , (events_process_t)events_process_open             },
        // and so on for 30 lines
};
static_assert(arraysize(events_processors) == EVENT_ID_LAST, "Update the table of events processors");

void some_code(int event_id)
{
        events_process_table_t *table = &events_processors[event_id];
        if (event_id == table->id)
        {
              // Looks alright and I can use the table->processor
              // ..... 
        }
}

最佳答案

我认为处理这种情况最有效的方法是使用一个将枚举值映射到它们相应的 C 字符串的函数:

enum class fruits { apple, orange, last };

char const* show(fruits x) {
    switch (x) {
        case fruits::apple: return "apple";
        case fruits::orange: return "orange";
        case fruits::last: return "last";
    }
    assert(false);
    return nullptr;
}

Live demo

在这一点上,如果您忘记在show 中定义fruits::last 的字符串,大多数编译器会警告您如下内容:

main.cpp: In function 'const char* show(fruits)':

main.cpp:7:12: warning: enumeration value 'last' not handled in switch [-Wswitch]

 switch (x) {

Live demo

如果您使用 -Werror 进行编译,将会阻止编译。

关于c++ - C++ 中的另一个静态数组初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35167723/

相关文章:

具有多重继承的 C++ 构造函数重载解决方案

c++ - 如何在 ffmpeg 的 h264 解码器中获取 pps 和 sps

c++ - 如何从 Linux 二进制文件中存储和检索数据

C++ cin.ignore 导致段错误?

arrays - 将静态数组转换为 Delphi 中的指针?

c - 当在c中输入空行时如何使此代码中的循环停止

javascript - 尝试在 JavaScript 中迭代 JSON 数组时出错

java - 尝试调用从另一个类定义变量的方法时出现编译错误

c++ - 如何在不传递类实例的情况下从静态成员函数调用非静态成员函数

android - 杀死 Android 服务和静态变量