c ++ 11 — C ++: как создать массив с id, строкой и именованной константой?

Я часто использую таблицы поиска const в моем коде, который состоит из идентификатора и строки. Но для удобства чтения было бы лучше использовать имена символов (именованные константы) вместо идентификатора.
Пример:

class LookupTable
{
map<int,string> m { {10,"red"}, {20,"blue"}, {30,"green"} };
enum { col_rd = 10, col_bl = 20, col_gr = 30 };
};

LookupTable tab;
cout << tab.m[10];      // "red", using the id
cout << tab.m[col_bl]   // "blue", using a symbol

cout << tab.m[11];      // Typo! Compiler does not check this
cout << tab.m[col_xy];  // Typo! Compiler will complain

Использование имен символов также будет проверяться на наличие опечаток во время компиляции.

Но мне нравится определять имя символа, идентификатор и строку для элемента в одном месте, вместо определения значений в верхней части, а затем определения именованных констант в нижней части объявления класса, особенно если таблица довольно длинная. Например, я хотел бы написать что-то вроде:

mytable.init = { { col_rd, 10, "red" },    // define the symbol names and
{ col_bl, 20, "blue" },   // values at one place
{ col_gr, 30, "green" } };

Это возможно сделать с помощью шаблонов или в сочетании с макросами #define?

-1

Решение

Однажды я видел эту технику в кэше Varnish, она использует макросы — но вы говорите, что с этим все в порядке 🙂

В color_tags.hpp:

// Define the color tags

COLOR_TAG(col_rd, 10, "red")
COLOR_TAG(col_bl, 20, "blue")
COLOR_TAG(col_gr, 30, "green")

Использование в main.cpp:

#include <map>
#include <string>
#include <iostream>

/// Enumeration of different color codes, we use a bit of
/// macro uglyness to makes this easy
enum class color_type
{
#define COLOR_TAG(id,value, msg) id = value,
#include "color_tags.hpp"#undef COLOR_TAG
terminate_tag
};

int main()
{
std::map<color_type, std::string> m =
{
#define COLOR_TAG(id, value, msg) {color_type::id, msg},
#include "color_tags.hpp"#undef COLOR_TAG
{color_type::terminate_tag, "undefined"}
};

std::cout << m[color_type::col_rd] << std::endl;
std::cout << m[color_type::col_bl] << std::endl;
std::cout << m[color_type::col_gr] << std::endl;

return 0;
}

Выход:

$ g++ main.cpp -std=c++11
$ ./a.out
red
blue
green
3

Другие решения

Идентификатор кажется мне бесполезным. Вы не можете сделать следующее?

struct LookupTable
{
enum ColorType
{
col_rd,
col_bl,
col_gr
}

std::map<ColorType, std::string> m;
};

Затем вы можете сделать что-то вроде:

LookupTable table;

table.m = {{LookupTable::col_rd, "red"},
{LookupTable::col_bl, "blue"},
{LookupTable::col_rd, "green"}};
5

По вопросам рекламы [email protected]