Подтвердить что ты не робот

Создание макроса с использованием __LINE__ для разных имен переменных

Возможный дубликат:
Создание макроса C С## и LINE (объединение маркеров с помощью макроса позиционирования)

Я пытаюсь использовать макрос __LINE__ для генерации разных имен переменных. У меня есть класс контрольных тестов под названием Benchmark (расположенный в пространстве имен utils), и конструктор берет строку. Вот определение макроса, которое я создал:

#define BENCHMARK_SCOPE utils::Benchmark bm##__LINE__(std::string(__FUNCTION__))

К сожалению, это вызывает следующую ошибку:

<some_file_name>(59): error C2374: 'bm__LINE__' : redefinition; multiple initialization

Это приводит меня к выводу, что макросы __LINE__ не расширяются. Я создал свой макрос в соответствии с этим сообщением. У вас есть идеи, почему __LINE__ не расширяется?

EDIT: возможно, информация компилятора также актуальна. Я использую visual studio 2010.

4b9b3361

Ответ 1

Вам нужно использовать комбинацию из 2 макросов:

#define COMBINE1(X,Y) X##Y  // helper macro
#define COMBINE(X,Y) COMBINE1(X,Y)

И затем используйте его как,

COMBINE(x,__LINE__);

Ответ 2

попробуйте этот код, я использовал его в более старом проекте

#define CONCATENATE_DIRECT(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
#ifdef _MSC_VER // Necessary for edit & continue in MS Visual C++.
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __COUNTER__)
#else
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
#endif 


int ANONYMOUS_VARIABLE(var)

EDIT:

Я думаю, вы должны использовать COUNTER в визуальной студии, только если также использовать предварительно скомпилированные заголовки.

Ответ 3

Вы используете вставку с маркером. Это происходит до рекурсивного макроса расширение (чтобы вы могли вставить токенную пасту, чтобы получить имя макроса, вы хотите вызвать). Таким образом:

#define PASTE(a,b) a ## b

вставляет точные аргументы, переданные в PASTE, затем пытаемся расширить новый токен. Чтобы получить необходимый эффект, вам понадобится дополнительный уровень косвенности:

#define PASTE_HELPER(a,b) a ## b
#define PASTE(a,b) PASTE_HELPER(a,b)

Здесь аргументы PASTE будут расширены до того, как PASTE_HELPER будет вызывается.