2009-07-25 3 views
5

Sto provando a scrivere un codice di libreria C++ portatile che inizialmente si baserà su Boost.Regex e quindi passare a TR1 come i compilatori supportano e infine al C++ Specifica 0x dopo che le cose vengono spostate dal namespace std :: tr1 a std. Ecco alcuni pseudo-codice per quello che mi piacerebbe fare con il preprocessore:Determinare l'esistenza in fase di compilazione dei file di inclusione in C++

if(exists(regex)) // check if I can #include <regex> 
{ 
    #include <regex> // per TR1 
    if(is_namespace(std::tr1)) // are we on TR1 or C++0x? 
    { 
     using std::tr1::regex; 
    } else 
    { 
     using std::regex; 
    } 
} else // fall-back to boost 
{ 
    #include <boost/regex.hpp> 
    using boost::regex; 
} 

Certo, tutto questo sarebbe bisogno di essere in direttive del preprocessore, ma se sapessi come realizzare che non avrei chiedile qui :)

risposta

10

Non è possibile farlo senza fare affidamento su una cosa di terze parti prima del preprocessing. Generalmente, cose come autoconf possono essere utilizzate per ottenere questo risultato.

Funzionano generando un altro file di intestazione con le direttive #define che indicano l'esistenza di intestazioni/librerie che si desidera utilizzare.

+0

Grazie per il chiarimento! :) – Zac

6

Non puoi farlo. La fase di pre-elaborazione di C++ avviene prima della fase di compilazione, quindi i costrutti condizionali del linguaggio C++ non possono essere posizionati utilmente attorno alle direttive del preprocessore come #include.

Se è necessaria la compilazione condizionale, il modo per farlo è utilizzare #ifdef. Qualcosa di simile:

#ifdef BOOST_BUILD 
    #include "somebooststuff.h" 
    using namespace boost; 
#else 
    #include "somestdstuff.h" 
    using namespace std; 
#endif 

dove BOOST_BUILD è un simbolo del preprocessore si definisce nel makefile o qualsiasi altra cosa.

+0

ho espressamente detto che non ero' t cercando di usare costrutti condizionali compilati C++. Più in particolare, sto cercando qualcosa di simile a una direttiva #ifdef che ha la funzionalità di verificare se il file include esiste: #ifexists (o qualcosa del genere) – Zac

+3

Non esiste tale funzionalità di preprocessore. Se hai davvero bisogno di fare questo 9e dubito che tu lo faccia) devi eseguire il tuo codice attraverso una sorta di script di elaborazione del testo scritto in qualcosa come perl o python prima di compilarlo. –

3

È possibile utilizzare la __cplusplus macro per vedere quale versione di C++ si sta lavorando con, nel prossimo standard (C++ 1x, C++0x isn't meant to be) avrà a value larger than 199711L

#if __cplusplus > 199711 
    using std::regex; 
#else 
    using std::tr1::regex; 
#endif