2010-05-30 24 views
5

¿Cuáles son las mejores prácticas para el uso autoconf en conjunción con shared_ptr y otros/BOOST TR1 plantillas de C++ 0x fin de maximizar la portabilidad y facilidad de mantenimiento?Cómo utilizar autoconf con C++ 0x cuenta

Con autoconf puedo determinar si es shared_ptr disponible como std::tr1::shared_ptr y/o boost::shared_ptr. Dada que la misma característica tiene dos nombres diferentes, tengo las siguientes preguntas:

  1. en el código, cómo debe ser referenciado shared_ptr?
  2. ¿Debería preferir std::tr1::shared_ptr a más de boost::shared_ptr?

Para el primero, el código está utilizando condicionales del preprocesador permitiendo referencias no calificadas para shared_ptr, a la

#if HAVE_STD_TR1_SHARED_PTR 
using std::tr1::shared_ptr; 
#elif HAVE_BOOST_SHARED_PTR 
using boost::shared_ptr; 
#else 
#error "No definition for shared_ptr found" 
#endif 

En segundo lugar, el código utiliza std::tr1:: sobre boost:: para minimizar dependencias de bibliotecas externas (incluso si las bibliotecas son ampliamente utilizado).

¿Son estas dos soluciones comunes? ¿Hay mejores?

Respuesta

3

Una mejora a su código de ejemplo, y una respuesta a su primera pregunta, es utilizar el "template typedef" modismo:

#if HAVE_STD_TR1_SHARED_PTR 
    template <class T> 
    struct SharedPtr { 
     typedef std::tr1::shared_ptr<T> Type; 
    }; 
#elif HAVE_BOOST_SHARED_PTR 
    template <class T> 
    struct SharedPtr { 
     typedef boost::shared_ptr<T> Type; 
    }; 
#else 
# error "No definition for shared_ptr found" 
#endif 

// Declare a shared_ptr using our wrapper classes, saving us from having to care 
// where shared_ptr comes from: 
SharedPtr<int>::Type my_shared_int(new int(42)); 

El principal problema con esto es la necesidad de utilizar la notación de tipo :: . Es puramente porque C++ actualmente no tiene forma de tener un typedef para una plantilla. Puede tener un typedef para una plantilla tipo instancia, pero aquí es importante que conservemos la genericidad.

En cuanto a si preferiría TR1 a Boost, diría que sí. Ahora que los compiladores envían con soporte parcial de C++ 0x, yo diría que también debes probar std :: shared_ptr y preferir eso a cualquiera de los demás.

Es posible que necesite un cuarto typedef si hay compiladores que tienen un shared_ptr que está en otro lugar. No sé de un compilador así, pero algún código C++ que mantengo hace algo similar a lo que está preguntando con la extensión slist común a la Biblioteca Estándar de C++, para listas de enlace único. Las versiones viejas de g ++ lo ubican en el espacio de nombres global, el g ++ moderno lo coloca en el espacio de nombres __gnu_cxx específico del compilador, ¡e incluso encontramos uno que erróneamente lo puso en std!

+0

No veo qué tipo de plantilla añade tu plantilla más que la sugerencia original del póster. Está "contaminado" con shared_ptr . Has contaminado cosas con SharedPtr :: Tipo. Ambos parecen equivalentes, y el suyo implica menos tipeo. ¿Qué cumple tu plantilla typedef más allá de la declaración using en la publicación original? –

+0

Lo tocas: ya no necesitas desplegar estos nombres en el espacio de nombres global. Mi método no necesariamente agrega nombres globales; puedes espacio de nombres si quieres. Y si no lo haces, es mucho menos probable que el mío entre en conflicto con los nombres en otra biblioteca. –

+0

Dado que shared_ptr eventualmente estará en std :: y que autoconf puede determinar en qué espacio de nombres se define shared_ptr, me inclino por "namespace std {using :: shared_ptr;}" si no se define std :: shared_ptr. – themis