Макрос C ++ не заменяет все значения - PullRequest
1 голос
/ 22 апреля 2010

У меня есть следующие 2 макроса:

#define SCOPED_ENUM_HEADER(NAME) struct NAME{ enum _NAME{
#define SCOPED_ENUM_FOOTER(NAME) };}; typedef NAME::_NAME NAMEtype;

Только первый экземпляр NAME заменяется на переданное NAME. Что с ним не так?

Используется таким образом:

 SCOPED_ENUM_HEADER(LOGLEVEL)
   UNSET,
   FILE,
   SCREEN
 SCOPED_ENUM_FOOTER(LOGLEVEL)

Ответы [ 2 ]

8 голосов
/ 22 апреля 2010

Проблема в том, что NAME отличается от _NAME; это два совершенно разных идентификатора.

Если вы хотите добавить подчеркивание к началу любого параметра NAME, используйте оператор объединения (##):

_##NAME

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

1 голос
/ 22 апреля 2010

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

Однако вы хотите взять значение NAME и связать что-то с ним, скажем, поставить E_ впереди. Это немного сложно, так как _##NAME обычно получит вам _NAME, независимо от того, что вы положили.

Это объясняется в C ++ FAQ Lite , но что вам действительно нужно сделать, это что-то вроде:

#define REALLY_CONCATENATE(a,b) a ## b
#define CONCATENATE(a,b) REALLY_CONCATENATE(a,b)
#define SCOPED_ENUM_HEADER(NAME) struct NAME{ enum CONCATENATE("E_", NAME) {

(извините, сейчас я не могу это проверить).

С другой стороны, должен быть лучший способ сделать то, что вы делаете. Серьезно.

...