2012-06-04 23 views
8

No estoy seguro de que el título de la pregunta sea correcto. Aquí está el problema Estoy escribiendo una biblioteca que utiliza algunas características de la biblioteca C++ 11. Es evidente que no todas las implementaciones son compatibles con estas bibliotecas y, por lo tanto, existe el problema de la portabilidad. No importa qué biblioteca sea de interés aquí. Una solución es usar boost, que ya proporciona muchas bibliotecas C++ 11. Así que mi solución es definir una macro, digamos USE_CXX11, y definir un nuevo espacio de nombres, por ejemplo internal, e introducir nombres en este espacio de nombres interno que depende de las macros. Por ejemplo, decir que necesito usar un nombre foo de una biblioteca de C++ <foo>, que también está disponible en <boost/foo/foo.hpp>. Lo que hago esC++ wrapper para boost/C++ 11

#ifdef USE_CXX11 
#include <foo> 
#else 
#include <boost/foo/foo.hpp> 
#endif 

namespace internal { 
#ifdef USE_CXX11 
using std::foo; 
#else 
using boost::foo::foo; 
#endif 
} 

Y en el resto de la biblioteca que sólo utilizan internal::foo. El código de terceros que utiliza esta biblioteca puede definir la macro adecuada para indicar si tienen una implementación de C++ 11 en funcionamiento o si solo pueden usar boost. Y mi biblioteca recogerá el encabezado y el espacio de nombres correctos. Esto funciona hasta ahora. Espero haber explicado bien mi intención.

Pero las soluciones anteriores me parecen muy feas. ¿Hay alguna mejor práctica para este tipo de cosas? ¿O hay situaciones posibles de que este enfoque no funcione?

+1

Salida ** ** Boost.TR1 –

+3

Si está en alza, y hay que apoyar compiladores obsoletos, solo use el de Boost directamente. –

+0

¿Por qué no usar boost? – fbafelipe

Respuesta

5

Su solución se ve bien para mí; el único problema será (como lo menciona Chet) en los casos en que difieran las interfaces y/o implementaciones de Boost y C++ 11.

De hecho, yo que en la biblioteca Boost.Algorithms (nuevo en la próxima versión 1,50)

namespace boost { namespace algorithm { 
#if __cplusplus >= 201103L 
using std::find_if_not;  // Section 25.2.5 
#else 
template<typename InputIterator, typename Predicate> 
InputIterator find_if_not (InputIterator first, InputIterator last, Predicate p) 
{ 
    for (; first != last; ++first) 
     if (!p(*first)) 
      break; 
    return first; 
} 
#endif 
}} 
2

No veo esto como una solución factible. La conmutación condicional entre clases restringirá su uso únicamente a aquellas funciones miembro que tengan las mismas firmas y semántica. También está redirigiendo el acceso a The Standard Library que puede parecer poco natural para muchos desarrolladores.

Si la usabilidad es una preocupación entre C++ 03 y C++ 11 entonces definitivamente deberías ir con Boost para todo. Si C++ 11 es su único objetivo, puede tener más éxito evaluando los diversos compiladores para ver qué características de lenguaje y biblioteca admiten. Elija aquellos que son bien compatibles y se consideran libres de errores. Para todo lo demás, utilice Boost y refactorizar más adelante si es necesario para admitir más características de la biblioteca C++ 11. Será mucho mejor utilizar las bibliotecas en tándem en lugar de cambiar entre ellas.

Puede comenzar con la página de estado de GCC's C++ Standard Library implementation.