2009-04-07 8 views
5

Stiamo programmando una libreria di registrazione che si mantiene in un file .hpp. Vorremmo includere <tr1/unordered_map> (se il compilatore supporta TR1,) o lo standard <map> in caso contrario. Esiste un modo standard per verificare in fase di compilazione se tr1 è disponibile o no?Come verificare la presenza di TR1 durante la compilazione?

Stavo pensando che allo stesso modo in cui è presente il simbolo di definizione "__cplusplus", potrebbe essere stato definito un "__cxx__tr1" o qualcosa del genere. Non l'ho visto nelle bozze di TR1, quindi presumo che non sia presente, ma volevo chiedere prima per ogni evenienza.

Come nota, se tali definizioni non esistono, non sarebbe una cattiva idea includerle nelle proposte stesse.

risposta

2

Se si sta utilizzando qualsiasi strumento di configurazione come autotools si può tentare di scrivere un test come:

AC_CHECK_HEADER(tr1/unordered_map,[AC_DEFINE([HAVE_TR1],[],["Have tr1"])],[]) 
AC_CHECK_HEADER(unordered_map,[AC_DEFINE([HAVE_CXX0X],[],["Have C++0x"])],[]) 

e quindi utilizzare queste definizioni nel codice.

In generale la macro __cplusplus dovrebbe fornire il numero di versione standard, ma non esiste un compilatore che fornisca un'implementazione standard al 100% ... Quindi scrivere le macro di configurazione.

Purtroppo questo è solo modo abbastanza affidabile per controllare queste cose a meno che non si desidera scrivere 1.001 #ifdef per ogni compilatore (che cosa spinta fa)

E poi:

#include "config.h" 
#ifdef HAVE_CXX0X 
# include <unordered_map> 
    typedef std::unordered_map<foo,bar> my_map; 
#elif HAVE_TR1 
# include <tr1/unordered_map> 
    typedef std::tr1::unordered_map<foo,bar> my_map; 
#else 
# include <map> 
    typedef std::map<foo,bar> my_map; 
#endif 
+0

OK, questa era un'opzione che volevo evitare, dato che voglio solo rilasciare un file .hpp ed eseguire. Per queste cose "quasi standard", preferirei un semplice confronto piuttosto che dover eseguire una configurazione completa. –

+0

Sto accettando questa risposta perché sembra che non ci sia modo, e questo sembra essere il modo migliore ... –

2

GCC-4.3 ha:

#define __GXX_EXPERIMENTAL_CXX0X__ 1 

Ma, questo non è ovviamente di serie.

+0

Questa macro viene definita se si utilizza g ++ -std = C++ 0x e quindi si ha unordered_map in std :: unordered_map. Altrimenti (no -std = C++ 0x) non hai questa definizione ma puoi comunque usare include e std :: tr1 :: unordered_map class. – Artyom

+0

Sì, ma come altri hanno sottolineato, questo è qualcosa che può essere testato solo durante la configurazione. Tutte le altre versioni di GCC precedenti alla 4.3 generano un errore quando viene fornito l'opzione -std. – greyfade

1

Una libreria con cui ho a che fare deve utilizzare alcune classi aggiunte a TR1 da Boost, preferendo TR1 se disponibile. La soluzione (essendo una libreria basata su Unix) è di inserire i controlli nello script configure.

Quindi in altre parole, niente, niente portatile che io conosca. Detto questo, se sei su Unix, i controlli dello script di configurazione funzionano abbastanza bene.

2

See ISO C++ (WG21) carta N1575. Questo documento è stato rimosso da TR1, senza alcuna sostituzione. Quindi non esiste un modo ufficiale per rilevare TR1.

+0

+1. Interessante. Non lo sapevo ... Peccato. –

0

Supponendo uno sta usando VS2010, o qualsiasi suite che ha TR1 disponibili, che cosa accadrebbe se si dovesse fare

#include "boost/tr1/unordered_map.hpp" 
... 
std::tr1::unordered_map<...> uMap; 

quale sarebbe il tipo di uMap essere?