2010-05-25 15 views
6

È possibile utilizzare un parametro di modello costante non di tipo in una direttiva di preprocessore? Ecco quello che ho in mente:Utilizzare un parametro di modello in una direttiva del preprocessore?

template <int DING> 
struct Foo 
{ 
    enum { DOO = DING }; 
}; 

template <typename T> 
struct Blah 
{ 
    void DoIt() 
    { 
     #if (T::DOO & 0x010) 

     // some code here 

     #endif 
    } 
}; 

Quando provo questo con qualcosa di simile Blah<Foo<0xFFFF>>, VC++ 2010 lamenta qualcosa su di parentesi senza eguali nella linea in cui stiamo cercando di utilizzare #if. Immagino che il preprocessore non sappia nulla dei template e questo genere di cose non è nel suo dominio. Cosa dire?

+0

Solo un punto da notare: 'Blah >' non analizzerà in corrente C++, è necessario uno spazio tra i> 's'. 'Blah >'. – KitsuneYMG

+0

In realtà, in VC++ 2010 viene compilato! :) Hanno parzialmente implementato C++ 0x in VC++ 2010. – Raj

risposta

11

No, questo non è possibile. Il preprocessore è piuttosto stupido e non ha alcuna conoscenza della struttura del tuo programma. Se T::Doo non è definito nel preprocessore (e non può essere, a causa dello ::), non può valutare quell'espressione e avrà esito negativo.

Tuttavia, si può fare affidamento sul compilatore di fare la cosa intelligente per voi:

 if (T::Doo & 0x010) { 
      // some code here 
     } 

espressioni costanti e rami secchi sono ottimizzati via anche le impostazioni di ottimizzazione più bassi, in modo da poter tranquillamente fare questo senza alcun sovraccarico di runtime.

+0

Questo non riuscirà a compilare se 'Doo' non è presente in' T'? –

+0

Grazie. È quello che pensavo. L'utilizzo del compilatore tuttavia non è l'ideale per me perché i membri disponibili in 'T' dipendono da quali bit sono impostati in' T :: DOO'. Sono sicuro che mi sto avvicinando a questo nel modo sbagliato. Immaginerò qualcos'altro. Ma era solo curioso di sapere fino a che punto possiamo andare con il preprocessore. Un'altra opzione potrebbe essere quella di vedere se i trucchi di meta-programmazione possono essere utilizzati per questo. – Raj

+0

Probabilmente possono. Se apri una nuova domanda con i dettagli di ciò che vuoi realizzare, possiamo dare un'occhiata. – Thomas

2

quali sono disponibili i membri a T dipende da quale bit sono impostati in T::DOO

Sembra a me come T::DOO agisce come un identificatore sottoclasse. Quindi penso che il tuo e le classi correlate dovrebbero essere sottoclassi di una classe che garantisce che sia definito DOO.

La chiave è: perché è necessario utilizzare un campo di bit?

+0

La risposta è un po 'complicata ma hai perfettamente ragione. Sto lavorando con questa API (DirectX) che consente una certa flessibilità nel specificare come si desidera formattare il contenuto di una determinata struttura passata come input a uno dei suoi metodi. Le informazioni su come è stata impostata la struttura sono passate attraverso un campo di bit. Nella mia app ho 2 astrazioni: la prima è una classe template che genera una raccolta di istanze di questa struct con il campo-bit e la struttura stessa passata come argomenti del template e un'altra che consuma questa raccolta. Commento cont.sotto – Raj

+0

Ho voluto scrivere del codice condizionale nella classe consumer che ha fatto uso di membri specifici di questa struttura controllando quali bit sono impostati nel campo di bit. Accidenti! Non sono sicuro di quanto avesse senso! Dato che ci sono varie istanze di template della classe sorgente mappate con diverse varianti della struttura, il codice in questione deve essere compilato in modo condizionale - da qui l'idea di provare a vedere se il preprocessore può essere usato. – Raj

1

Non sono sicuro se questo si applica alla situazione, ma è possibile isolare diversi casi con classi di modelli. Per esempio: (utilizzando una versione modificata del codice dall'alto)

template <typename T, int N> 
struct Blah 
{ 
    void DoIt() 
    { 
     // normal DoIt() code 
    } 
}; 

template <typename T> 
struct Blah<T,5> 
{ 
    void DoIt() 
    { 
     // special DoIt() code for only when N==5 
    } 
}; 
Problemi correlati