Переопределение X-Macros - PullRequest
       12

Переопределение X-Macros

1 голос
/ 03 февраля 2010

Когда я включаю «xmacro.h» в заголовочный файл, который используется несколькими заголовочными файлами, я получаю ошибку компоновки:

Ошибка LNK2005: "char const * * iD_Strings" (? ID_Strings @@ 3PAPBDA) уже определено в header_file.obj

1.//"xmacro.h"
2.
3.// (1) Define code generating macro
4.
5.   #ifndef XMACRO_H
6.   #define XMACRO_H
7.
8.    #define GENERATE_IDS \
9.   X(_Name, "/Name") \
10.   X(_ID, "/ID")
11.
12.  // (2) Define X-Macro for generating enum members
13.
14.  #define X(id, idString) id, 
15.   enum IDs
16.  {
17.     ID_LOWERBOUND = -1,
18.    GENERATE_IDS
19.   NUM_IDS
20.  };
21.  #undef X
22.
23.  // (3) Define X-Macro for generating string names
24.
25.  #define X(id, idString) idString,
26.  const char* iD_Strings[] =
27.  {   
28.     GENERATE_IDS
29.     NULL
30.  };
31.  #undef X
32.
33.  #endif

выдает ошибку, когда я определяю X-Macro для генерации имен строк в строке 23. как бы я использовал один макрос, не переопределяя его?

Ответы [ 2 ]

3 голосов
/ 03 февраля 2010

Ваш заголовочный файл содержит определение из iD_Strings. Когда вы включаете его из разных исходных файлов, он связывается несколько раз. Это приводит к конфликту, даже если определения идентичны.

Вы можете объявить iD_Strings как static (способ C) или обернуть его в анонимное пространство имен (способ C ++), чтобы обойти эту проблему.

1 голос
/ 12 февраля 2010

Лучший способ сделать X-макросы (которые я всегда называл списочными макросами) - это передать оператор в качестве параметра в список, тогда вы можете хранить несколько «операторов» одновременно:

#define GENERATE_IDS(_) \
_(Name) \
_(Id)

enum IDs
{
    ID_LOWERBOUND = -1,
    #define MK_ID_ENUM(n) _##n,
    GENERATE_IDS(MK_ID_ENUM)
    NUM_IDS
}

const char* iD_Strings[] =
{
    #define MK_ID_STRING(n) "/" #n,
    GENERATE_IDS(MK_ID_STRING)
    NULL
};

Обратите внимание, что вы все равно должны объявлять идентификаторы однозначно, но вызов макроса GENERATE_IDS () для объявления объектов действительно принадлежит телу .c / .c ++, а не заголовку в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...