En la mayoría de los aspectos, el std::unique_ptr
fue hecho para ser gota en el reemplazo (pero más seguro) para std::auto_ptr
, por lo que debe ser muy pocos (si los hay) los cambios de código requiere que no sea (como se le pregunte) dirigir el código para utilizar cualquiera unique_ptr
o auto_ptr
.
Hay algunas maneras de hacer esto (y cada una viene con sus propias compensaciones de lista) a continuación. Dado el ejemplo de código proporcionado, preferiría cualquiera de las dos primeras opciones .
Opción 1
#if __cplusplus >= 201103L
template <typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif
Compensaciones;
- Introduce el
auto_ptr
nombre en el espacio de nombres global; puede mitigar esto definiendo que es su propio espacio de nombres "privado"
- Una vez que migre a C ++ 17 (creo
auto_ptr
que se eliminará por completo), puede buscar y reemplazar más fácilmente
opcion 2
template <typename T>
struct my_ptr {
#if __cplusplus >= 201103L
typedef std::unique_ptr<T> ptr;
#else
typedef std::auto_ptr<T> ptr;
#endif
};
Compensaciones;
- Probablemente más engorroso para trabajar, toda la
auto_ptr
necesidad actual de cambiar en el código a algo comomy_ptr<T>::ptr
- Mejor seguridad: los nombres no se están introduciendo en el espacio de nombres global
Opción 3
Algo controvertido, pero si estás preparado para soportar las advertencias de tener una std
clase como base
#if __cplusplus >= 201103L
template <typename T>
using my_ptr = std::unique_ptr<T>;
#else
template <typename T>
class my_ptr : public std::auto_ptr<T> {
// implement the constructors for easier use
// in particular
explicit my_ptr( X* p = 0 ) : std::auto_ptr(p) {}
};
#endif
Compensaciones;
- No intente utilizar la clase heredada donde se esperaría una base virtual (en particular, wrt, el destructor no virtual). No es que esto deba ser un problema en el caso, pero ten en cuenta
- De nuevo, el código cambia
- Posibles desajustes del espacio de nombres: todo depende de cómo se use la clase de puntero para empezar
Opcion 4
Envuelva los punteros en una nueva clase y agregue las funciones requeridas al miembro
template <typename T>
class my_ptr { // could even use auto_ptr name?
#if __cplusplus >= 201103L
std::unique_ptr<T> ptr_;
#else
std::auto_ptr<T> ptr_;
#endif
// implement functions required...
T* release() { return ptr_.release(); }
};
Compensaciones;
- Un poco extremo cuando todo lo que realmente quieres es "intercambiar" las implementaciones
auto_ptr
Alguno de los ámbitos (es decirstd::auto_ptr
), ¿deben ser o se puede obtener el puntero inteligente de algún otro espacio de nombres?