2014-06-30 7 views
10

Nessuna virgola è consentita in un argomento macro poiché verrà trattata come più di un argomento e la preelaborazione sarà errata. Tuttavia, possiamo parentesi l'argomento per consentire al preprocessore di trattarlo come un argomento. C'è una macro o altre tecniche che possono rimuovere le parentesi che racchiudono?Come rimuovere le parentesi racchiudenti con macro?

Per esempio, se io definisco una macro come

#define MY_MACRO(a, b) ... 

e utilizzarlo come

MY_MACRO(A<int, double>, text); 

sarà sbagliato. usalo come

MY_MACRO((A<int, double>), text) 

con una macro o tecnica per rimuovere le parentesi andrà bene. Boost offre BOOST_IDENTITY_TYPE macro solo per i tipi, ma non casi generali

+1

A work around - 'typedef A IA; MY_MACRO (IA, text); ' –

+1

Il typedef è più elegante di tutti gli hack del preprocessore IMHO –

risposta

14
#define ESC(...) __VA_ARGS__ 

poi

MY_MACRO(ESC(A<int, double>), text); 

potrebbe fare quello che vuoi.

+0

Wow. Così bello e semplice! – user1899020

+0

in alternativa l'ESC può andare in MY_MACRO, ad es. '#define MY_MACRO (a, b) ESC a (b)' 'MY_MACRO ((A ), testo);' -> 'A (testo);' (dichiarazione variabile) –

1

Un semplice hack potrebbe essere quella di utilizzare le macro variadic:

#define MY_MACRO(a, b...) ... 

Quindi è possibile utilizzarlo come:

MY_MACRO(text, A<int, double>) 

La virgola nel secondo argomento è ancora interpretato come separatore argomento (che significa la macro viene effettivamente chiamata con tre argomenti), ma è espansa all'interno della macro, rendendo il comportamento lo stesso. L'argomento variadico deve essere l'ultimo nella macro, tuttavia.

4

Questo trucco macro è simile alla soluzione di Yakk ma rimuove la necessità di passare esplicitamente in un'altra macro come parametro.

#include <stdio.h> 

#define _Args(...) __VA_ARGS__ 
#define STRIP_PARENS(X) X 
#define PASS_PARAMETERS(X) STRIP_PARENS(_Args X) 

int main() 
{ 
    printf("without macro %d %d %d %d %d %d\n", (5,6,7,8,9,10)); // This actually compiles, but it's WRONG 
    printf("with macro %d %d %d %d %d %d\n", PASS_PARAMETERS((5,6,7,8,9,10))); //Parameter "pack" enclosed in parenthesis 
    return 0; 
} 

Naturalmente si potrebbe essere creativi, rendendo la macro PASS_PARAMETERS in una macro variadic e passare confezioni multiple di parametri.