2009-04-07 8 views
5

Estamos programando una biblioteca de registro que se mantiene en un archivo .hpp. Nos gustaría incluir <tr1/unordered_map> (si el compilador admite TR1,) o el estándar <map> en caso contrario. ¿Existe una forma estándar de verificar en tiempo de compilación si tr1 está disponible o no?¿Cómo verificar para TR1 mientras compila?

Estaba pensando que de la misma manera que el símbolo de definición "__cplusplus" está presente, se podría haber definido un "__cxx__tr1" o algo así. No lo he visto en los borradores de TR1, así que supongo que no está presente, pero quería preguntar primero por las dudas.

Como nota, si esas definiciones no existen, no sería una mala idea incluirlas en las propuestas.

Respuesta

2

Si está utilizando cualquier herramienta de configuración como autotools es posible que trate de escribir una prueba como:

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

Y a continuación, utilizar estos define en el código.

En general, el macro __cplusplus debe darle el número de versión estándar, pero no hay un compilador que le proporcione una implementación 100% estándar ... Por lo tanto, escriba configure macros.

Por desgracia, esta es única manera bastante fiable para comprobar este tipo de cosas a menos que desee escribir 1001 #ifdef para cada compilador (lo que impulso hace)

Y luego:

#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, esa era una opción que quería evitar, ya que solo quiero lanzar un archivo .hpp y ejecutarlo. Para estas cosas "casi estándar", preferiría una comparación simple en lugar de tener que ejecutar una configuración completa. –

+0

Estoy aceptando esta respuesta, ya que parece que no hay forma, y ​​esta parece ser la mejor manera ... –

2

GCC-4.3 tiene:

#define __GXX_EXPERIMENTAL_CXX0X__ 1 

embargo, esto obviamente no es estándar.

+0

Esta macro se define si usa g ++ -std = C++ 0x y luego tiene unordered_map en std :: unordered_map. De lo contrario (no -std = C++ 0x) no tiene esta definición, pero aún puede usar la clase include y std :: tr1 :: unordered_map. – Artyom

+0

Sí, pero como otros han señalado, esto es algo que solo se puede probar durante la configuración. Todas las demás versiones de GCC anteriores a 4.3 arrojan un error cuando se da ese -std switch. – greyfade

1

Una biblioteca que trato necesita utilizar algunas clases que se agregaron a TR1 de Boost, prefiriendo TR1 si está disponible. La solución (al ser una biblioteca basada en Unix) es meter los cheques en el script de configuración.

Así que en otras palabras, no, nada portátil que yo sepa. Dicho esto, si está en Unix, las secuencias de comandos de configuración funcionan lo suficientemente bien.

2

Véase ISO C++ (WG21) papel N1575. Este documento ha sido eliminado de TR1, sin reemplazo. Entonces no hay forma oficial de detectar TR1.

+0

+1. Interesante. No lo sabía ... Lástima. –

0

Suponiendo que uno está usando VS2010, o cualquier suite que tiene TR1 disponibles, lo que ocurriría si uno fuera a hacer

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

Lo que sería el tipo de uMap ser?

Cuestiones relacionadas