2016-02-11 2 views
4

Я хотел бы иметь возможность создать макрос, который вызывает другие макросы. Макрос, который я бы назвал, это макрос Benchmark от folly.Как использовать макросы в вызове другого макроса?

В конце концов, я хотел бы иметь кучу макросов, которые выглядят как:

BENCHMARK(filter_10_vector_1_filter, n) { ... } 
BENCHMARK(filter_10_set_1_filter, n) { ... } 
BENCHMARK(filter_10_vector_2_filter, n) { ... } 
BENCHMARK(filter_10_set_2_filter, n) { ... } 
BENCHMARK(filter_10_vector_3_filter, n) { ... } 
BENCHMARK(filter_10_set_3_filter, n) { ... } 
... all the way to 10_filter 

BENCHMARK(filter_100_vector_1_filter, n) { ... } 
BENCHMARK(filter_100_set_1_filter, n) { ... } 
... all the way to 10_filter 

Я попытался создать макрос, который выглядит как:

#define CreateBenchmark(numElements, numFilters) \ 
    BENCHMARK(filter_##numElements_vector_##numFilters_filters, n) { ... } \ 
    BENCHMARK_RELATIVE(filter_##numElements_set_##numFilters_filters, n) { ... } 

CreateBenchmark(10, 2); 

, который, мы надеемся сократить вдвое число макросов мне нужно написать. Однако замены ##numElements и ##numFilters не происходят, как я надеялся. Результат CreateBenchmark(10, 2) вызова

============================================================================ 
FilterWithSetBenchmark.cpp relative time/iter iters/s 
============================================================================ 
filter_numElements_vector_numFilters_filters    264.35us 3.78K 
filter_numElements_set_numFilters_filters   99.93% 264.54us 3.78K 
============================================================================ 

Я ожидал filter_10_vector_2_filters и fitler_10_set_2_filters. Есть ли способ подставить значения, предоставленные в макрос CreateBenchmark, в значения, переданные в вызовы BENCHMARK и BENCHMARK_RELATIVE?

В качестве бонуса, может ли мой CreateBenchmark макрос использовать для цикла, чтобы создать все XX_filters так, что один вызов CreateBenchmark генерирует 20 макро-вызовов (10 для _vector_ и 10 для _set_)?

+1

Спасибо за то, что может быть первым разумным использованием '##', которое я когда-либо видел. Используете ли вы триграфы? –

+0

Без проблем, наверное? : p В каких ситуациях обычно вы видите '##'? Нет, я не использую триграфы, просто пишу некоторые обычные контрольные тесты с использованием кода. –

+0

Не думаю, что я видел '##' вне полностью надуманных примеров. Вот как я думал о триграфах. –

ответ

4

Вы забыли трейлинг конкатенации оператор ##:

#define CreateBenchmark(numElements, numFilters) \ 
    BENCHMARK(filter_ ## numElements ## _vector_ ## numFilters ## _filters, n) { ... } \ 
    BENCHMARK_RELATIVE(filter_ ## numElements ## _set_ ## numFilters ## _filters, n) { ... } 

Думают о ## как оператор конкатенации так же, как + в Java или Python.

-2

Вы можете использовать __VA_ARGS__ для представления макро аргументов.

+2

Как бы это было отдаленно применимо к ситуации с ОП? –

1

Выявлено это случайно. Моей функции создания макроса понадобилось больше #. Вот новый:

#define CreateBenchmark(numElements, numFilters) \ 
    BENCHMARK(filter_##numElements##_vector_##numFilters##_filters, n) { ... } \ 
    BENCHMARK_RELATIVE(filter_##numElements##_set_##numFilters##_filters, n) { ... } 

В общем, что я хочу подкровать должен быть полностью заключен в двойной #. Прошел от ##numElements до ##numElements##. Аналогично для numFilters.

Смежные вопросы