Напротив С препроцессор "Струнизация" - PullRequest
38 голосов
/ 08 августа 2011

При использовании препроцессора C можно привести строковый аргумент макрокоманды так:

#define TO_STRING(x) "a string with " #x

и так при использовании, результат будет следующим:

TO_STRING(test) расширится до: "a string with test"

Есть ли способ сделать обратное? Получить строковый литерал в качестве входного аргумента и создать идентификатор C? Например:

TO_IDENTIFIER("some_identifier") расширится до: some_identifier

Спасибо за ваши ответы.

РЕДАКТИРОВАТЬ: Для тех, кому интересно, зачем мне это нужно:

Я хотел ссылаться на узлы в графе сцены моего трехмерного движка по строковым идентификаторам, но в то же время избегать сравнения строк в тесных циклах. Поэтому я подумал, что напишу простой инструмент, который будет запускаться на этапе предварительной компиляции и искать предопределенную строку - например, ID("something"). Затем для каждого такого токена он будет вычислять CRC32 строки между скобками и генерировать файл заголовка с #defines, содержащим эти числовые идентификаторы. Например, для строки "something" это будет:

#define __CRC32ID_something 0x09DA31FB

Затем сгенерированный заголовочный файл будет включен в каждый файл cpp с использованием макросов ID(x). ID("something"), конечно, расширится до __CRC32ID_something, поэтому, по сути, компилятор увидит простые целочисленные идентификаторы вместо строк, дружественных человеку. Конечно, теперь я просто соглашусь на ID(something), но я подумал, что использование кавычек будет более целесообразным - программист, который не знает, как работает макрос ID, может подумать, что something без кавычек является идентификатором C, когда на самом деле такого идентификатора не существует вообще.

Ответы [ 2 ]

26 голосов
/ 08 августа 2011

Нет, вы не можете что-то без стрижки.

0 голосов
/ 24 мая 2013
//unstringify test

enum fruits{apple,pear};

#define IF_WS_COMPARE_SET_ENUM(x) if(ws.compare(L#x)==0)f_ret=x;

fruits enum_from_string(wstring ws)
{
 fruits f_ret;
 IF_WS_COMPARE_SET_ENUM(apple)
 IF_WS_COMPARE_SET_ENUM(pear)
 return f_ret;
}

void main()
{
 fruits f;
 f=enum_from_string(L"apple");
 f=enum_from_string(L"pear");
}
...