2016-10-30 5 views
-2
#define STRIP0 0 
#define STRIP1 1 
#define STRIP2 2 
#define STRIP3 3 
#define PINS0 2,3,4 
#define PINS1 5,6,7 
#define PINS2 8,9,10 
#define PINS3 11,12,13 

#define PINS(STRIP) { (STRIP) == (STRIP0) ? PINS0 :\ 
         (STRIP) == (STRIP1) ? PINS1 :\ 
         (STRIP) == (STRIP2) ? PINS2 :PINS3} 

теперь, если когда я вызвать функцию, которая принимает 3 аргумента все типа междунар foo(int,int,int); как это foo(PINS1); то функция компилируется и работает, как и ожидалось (все аргументы передаются как если #define был заменен на «5,6,7»)Использование макросов для выбора аргументов функции

, но если я использую макрос для выбора набора контактов, например foo(PINS(STRIP1));, тогда выбор аргумента будет угасать. в этом конкретном случае список ошибочных аргументов становится «7,12,13», а для foo(PINS(STRIP0)); он становится «4,12,13», есть образец, который я вижу, но у меня нет опыта, чтобы рассказать и исправить то, что происходит при компиляции время.

+0

Если вы используете макрос функций типа «PINS», у вас есть две проблемы: первая - фигурные скобки, которые у вас есть вокруг всего выражения. Во-вторых, вместо передачи нескольких аргументов вы передаете один аргумент, потому что тогда запятая становится и разделителем аргументов, а выражением для запятой. Вы должны пересмотреть свое использование макросов, возможно, вместо этого используется оболочка 'inline'? Или, по крайней мере, изменить макрос, возможно, взять функцию в качестве аргумента и вызвать вызов внутри макроса «тело»? –

+0

Почему бы вам просто не написать 'if/else' – Danh

+0

@Someprogrammerdude, я удалю фигурные фигурные скобки и отредактирую вопрос, но это не повлияет на результат. , когда я делаю это 'foo (PINS1);' (как указано в вопросе), функция принимает 3 числа в качестве самих аргументов, что заставило меня поверить, что запятая как выражение не происходило, а компилятор признал, что есть 3 аргумента и что почему это продолжалось. Это причина, по которой я думал, что макрос, который выбирает 'PINS0' или' PINS1', будет работать, но это не так. Ваше предложение о том, чтобы функция как аргумент в макросе, вероятно, то, что предлагает krzaq –

ответ

0

Имо, вы сильно ущемляете читаемость, используя для этого макросы. Но вот как бы я это сделать:

#define STRIP0 0 
#define STRIP1 1 
#define STRIP2 2 
#define STRIP3 3 
#define PINS0 2,3,4 
#define PINS1 5,6,7 
#define PINS2 8,9,10 
#define PINS3 11,12,13 

#define CONCAT_HELP(A, B) A ## B 

#define CONCAT(A, B) CONCAT_HELP(A, B) 

#define PINS(FUNC,STRIP) FUNC(CONCAT(PINS, STRIP)) 

сейчас, вы бы назвали это так:

PINS(foo, STRIP0); 

demo

Вам нужно два уровня косвенности, из-за способа макро замены (here - подробное объяснение). Только с #define CONCAT(A,B) A ## B, CONCAT(PINS,STRIP0) создаст PINSSTRIP0, что не имеет смысла здесь.


Для полноты, если вы собираетесь использовать это со значениями времени выполнения (из которых не давали никаких указаний в этом вопросе), вы могли бы пойти с шаблоном функции помощника, который будет переключать значение полосы:

template<typename Func> 
void pins(Func f, int strip) 
{ 
    switch(strip){ 
    case 0: f(PINS0); break; 
    case 1: f(PINS1); break; 
    case 2: f(PINS2); break; 
    case 3: f(PINS3); break; 
    } 
} 

demo

и, если у вас есть C++ 17 доступны:

constexpr tuple<int,int,int> params[] = { 
    make_tuple(PINS0), 
    make_tuple(PINS1), 
    make_tuple(PINS2), 
    make_tuple(PINS3) 
}; 

template<typename Func> 
void pins(Func f, int strip) 
{ 
    apply(f, params[strip]); 
} 

demo

хотя в этот момент вспомогательная функция перестает быть необходимой.

+1

Мне определенно нужен был мой кофе. Хороший ответ, но, возможно, уместно объяснить * почему * требуется промежуточное расширение. ОП, похоже, не очень хорошо разбирается. – StoryTeller

+0

@StoryTeller добавлен. – krzaq

+1

Целью, которую я пытаюсь выполнить, является то, что каждый набор PINS0 соответствует другому набору физических контактных соединений, которые не изменяются во время выполнения и должны передаваться в качестве аргументов для различных функций , поэтому делая что-то подобное, я сохраню проблема изменения этих определений везде, где все! Я попробую ваш ответ, похоже, что он должен работать @StoryTeller Я не очень хорошо разбираюсь, спасибо всем за помощь ;-) –

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