2015-09-04 35 views
6

ho trovato una domanda che mostra come sovraccaricare le macro in base al numero di argomenti: Overloading Macro on Number of Arguments__VA_ARGS__ espansione usando MSVC

Ma come si dice, non funziona usando MSVC perché MSVC espande __VA_ARGS__ in un unico token invece di un elenco degli argomenti (arg1, arg2, arg3).

a cui puntano un'altra domanda dove intorno viene dato un lavoro: MSVC doesn't expand __VA_ARGS__ correctly Ma non ha spiegato a tutti, quindi non posso adattarlo al mio caso visto che non riesco a capire.

Potrebbe spiegare come funziona questa soluzione alternativa?

+0

Penso che il post collegato non sia corretto. Penso che la soluzione giusta sia 'G (...) F (EXPAND (__ VA_ARGS__))' – LPs

+0

@LPs, l'ho pensato anch'io, ma provalo. –

+0

@JohnBollinger Sono troppo Linux dentro per mettere le mani su MSVC :). Seriamente, non ho MSVC per testarlo. Lascia che OP lo provi – LPs

risposta

9

La soluzione in questione è questo:

#define EXPAND(x) x 
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__ 
#define G(...) EXPAND(F(__VA_ARGS__)) 

L'idea è che, dato uno esistente variadic macro F():

#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__ 

invece di scrivere macro involucro variadic desiderato come, in questo caso, ...

#define G(...) F(__VA_ARGS__) 

... si scrive G() con l'uso della macro EXPAND() aggiuntiva. La definizione attuale di F() non è il punto, e in particolare non è rilevante per questo esempio che l'espansione macro non produca codice C valido. Il suo scopo è dimostrare il comportamento del preprocessore rispetto agli argomenti macro. Nello specifico, mostra che sebbene MSVC espanda __VA_ARGS__ in un singolo token in una macro variadic, ciò può essere aggirato forzando una doppia espansione.

Ad esempio, utilizzando la definizione soluzione, il preprocessore prima espande ...

G(1, 2, 3) 

... al ...

EXPAND(F(1, 2, 3)) 

... dove il 1, 2, 3 viene considerato come gettone singolo. Tale tokenizzazione non ha più importanza quando il preprocessore esegue la copia per sostituzioni aggiuntive, tuttavia: vede lo 1, 2, 3 come argomenti separati alla macro F() e lo espande come desiderato per produrre l'argomento della macro EXPAND(), che lo sostituisce con se stesso.

Se ritieni strano che funzioni come previsto, ma la versione senza EXPAND() non funziona (in MSVC), hai ragione.

+0

grazie per il tuo aiuto! lo vedrò più tardi! – Virus721

+0

Funziona, grazie. Lo capisco anche meglio ora. Chiamando la macro dove gli argomenti dovrebbero essere espansi usando un'altra macro, il compilatore espande correttamente gli argomenti. – Virus721

+0

In realtà il mio caso è leggermente diverso. Vorrei sovraccaricare in base al numero di argomenti: 1 arg -> metodo per 1 arg, 2 args -> metodo per 2 arg. BUT: Mi piacerebbe anche che> 2 args -> metodo per 2 args + va args, dato che i due overload per la mia macro possono avere una lista di argomenti dopo i loro parametri obbligatori. Questo mi crea un problema, perché quando chiamo il mio metodo con> 2 args, allora il terzo argomento è usato come nome del metodo, che è sbagliato. – Virus721