2009-04-07 12 views
5

Nous programmons une bibliothèque de journalisation qui se conserve dans un fichier .hpp. Nous aimerions inclure <tr1/unordered_map> (si le compilateur prend en charge TR1,) ou le standard <map> sinon. Existe-t-il un moyen standard de vérifier au moment de la compilation si tr1 est disponible ou non?Comment vérifier TR1 lors de la compilation?

Je pensais que de la même façon que le symbole de définition "__cplusplus" est présent, il aurait pu être défini un "__cxx__tr1" ou quelque chose comme ça. Je n'ai pas vu cela dans les projets pour TR1, donc je suppose qu'il n'est pas présent, mais je voulais demander d'abord au cas où. En tant que note, si ces définitions n'existent pas, il ne serait pas une mauvaise idée de les inclure dans les propositions elles-mêmes.

Répondre

2

Si vous utilisez des outils de configuration comme autotools vous pouvez essayer d'écrire un test comme:

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

Et puis utilisez ces définit dans votre code. En règle générale, la macro __cplusplus devrait vous donner le numéro de version standard, mais il n'y a pas de compilateur qui vous donne une implémentation standard à 100% ... Écrivez donc des macros de configuration.

Malheureusement, c'est seul moyen de vérifier tout à fait fiable des choses, sauf si vous voulez écrire 1001 #ifdef pour chaque compilateur (ce boost ne)

Et puis:

#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, c'était une option que je voulais éviter, car je veux juste sortir un fichier .hpp et l'exécuter. Pour ces choses "presque standard", je préférerais une comparaison simple plutôt que d'avoir à exécuter une configuration à part entière. –

+0

J'accepte cette réponse car il semble qu'il n'y a aucun moyen, et cela semble être le meilleur moyen ... –

2

GCC-4.3 a:

#define __GXX_EXPERIMENTAL_CXX0X__ 1 

Mais, ce qui est évidemment pas standard.

+0

Cette macro est définie si vous utilisez g ++ -std = C++ 0x et que vous avez unordered_map dans std :: unordered_map. Sinon (non -std = C++ 0x) vous n'avez pas cette définition mais vous pouvez toujours utiliser la classe include et la classe std :: tr1 :: unordered_map. – Artyom

+0

Oui, mais comme d'autres l'ont fait remarquer, c'est quelque chose qui ne peut être testé que pendant la configuration. Toutes les autres versions de GCC avant 4.3 lancent une erreur lorsque le commutateur -std est donné. – greyfade

1

Une bibliothèque que je traite doit utiliser certaines classes ajoutées à TR1 à partir de Boost, préférant TR1 si disponible. La solution (qui est une bibliothèque basée sur Unix) consiste à placer les vérifications dans le script de configuration. Donc, en d'autres termes, non, rien de portable que je connaisse. Cela dit, si vous utilisez Unix, les vérifications de scripts de configuration fonctionnent assez bien.

2

Voir ISO C++ (WG21) papier N1575. Ce document a été supprimé de TR1, sans remplacement. Il n'y a donc aucun moyen officiel de détecter TR1.

+0

+1. Intéressant. Je ne savais pas ... Dommage. –

0

En supposant l'on utilise VS2010, ou une suite qui a TR1 disponible, ce qui se passerait si l'on devait faire

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

Quel serait le type de uMap être?