(Как) я могу использовать массив строк в качестве идентификаторов в C++?

Я работаю над этим проектом, где мне нужно разобрать текстовый файл, содержащий таблицу из двух столбцов, состоящую из имен слева и значений справа.

Теперь мне нужно записать их в определенные места в контрольной таблице, которые идентифицируются с использованием шестнадцатеричных адресов; в файле заголовка, который я не могу редактировать, они были определены как таковые:

#define HARRY_POTTER 0x3A

Там есть функция записи, которая берет адрес и значение и записывает его в место хранения (эта функция также не входит в мой контроль). Итак, называя это

write(0x3A, 7);

Имеет тот же результат, что и вызов этого

write(HARRY_POTTER, 7);

Из-за этого определения в файле заголовка.

Теперь у меня разбор, который в основном дает мне левый столбец, имя, как строку (например, "HARRY_POTTER", например), а правый столбец - как целое число.

Мне интересно, есть ли способ использовать эту строку, "HARRY_POTTER" как идентификатор в функции записи; по существу преобразовывая строку в идентификатор, чтобы я мог просто пропустить весь массив проанализированных значений и автоматически записать их на адрес, соответствующий строке/имени в левом столбце.

Это возможно? Если да, то как?

2 ответа

Нет, это невозможно, как вы просите. Причина в том, что строка, которую вы читаете из файла, известна только во время выполнения, а предварительная обработка происходит во время компиляции, поэтому HARRY_POTTER уже должен быть заменен. Фактически, никакие идентификаторы вообще не существуют после того, как программа была скомпилирована.

Что вам может понадобиться, чтобы ввести сопоставление из std::string в константы, которые вы определили. Например:

std::unordered_map<std::string, int=""> mapping = {{"HARRY_POTTER", HARRY_POTTER},
 {"RON_WEASLEY", RON_WEASLEY}};
</std::string,>

Конечно, константы будут заменены во время компиляции, так что это просто эквивалентно:

std::unordered_map<std::string, int=""> mapping = {{"HARRY_POTTER", 0x3A},
 {"RON_WEASLEY", 0x7C}};
</std::string,>

После этого вы можете позвонить write с:

write(mapping.at(key), 7);

Где key - это строка со значением, как "HARRY_POTTER".


(Этот ответ лучше подходит в комментарии, но я все еще работаю над репутацией...)

Я согласен с Джозефом, что путь - это std :: unordered_map в С++ 11 или std :: map в С++ 03.

Я только хотел добавить, что вы можете сделать код намного более удобным и легким для записи с помощью макромагии в этом случае.

/* The stringify macro converts x to "x" at compile-time. */
#define _stringify(x) # x
#define stringify(x) _stringify(x)

/* Macro easing the assignment of { "String", value } */
#define STR_VAL(x) { stringify(x), (x) }

/* Now you can write the assignment code as follows */
std::unordered_map<std::string, int=""> mapping = {
 STR_VAL(HARRY_POTTER),
 STR_VAL(RON_WEASLEY), 
 STR_VAL(ALBUS_BRIAN_WULFRIC_PERCIVAL_DUMBLEDORE)
};
</std::string,>

Это означает, что если значение параметра #define HARRY_POTTER когда-либо изменится, ваш код сопоставления будет автоматически обновляться при перекомпиляции.

licensed under cc by-sa 3.0 with attribution.