Em muitos aspectos, a std::unique_ptr
substituição foi feita (mas é mais segura) std::auto_ptr
, portanto, deve haver muito poucas (se houver) alterações de código necessárias além de (como você pede) direcionando o código para usar um unique_ptr
ou outro auto_ptr
.
Existem algumas maneiras de fazer isso (e cada uma vem com suas próprias vantagens e desvantagens da lista) abaixo. Dado o exemplo de código fornecido, eu preferiria uma das duas primeiras opções .
Opção 1
#if __cplusplus >= 201103L
template <typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif
Tradeoffs;
- Você introduz o
auto_ptr
nome no espaço para nome global; você pode atenuar isso definindo que é seu próprio espaço para nome "privado"
- Depois de migrar para o C ++ 17 (acredito
auto_ptr
que será completamente removido), você poderá pesquisar e substituir mais facilmente
opção 2
template <typename T>
struct my_ptr {
#if __cplusplus >= 201103L
typedef std::unique_ptr<T> ptr;
#else
typedef std::auto_ptr<T> ptr;
#endif
};
Tradeoffs;
- Provavelmente mais complicado de se trabalhar, toda a
auto_ptr
necessidade atual mudou de código para algo comomy_ptr<T>::ptr
- Melhor segurança: os nomes não estão sendo introduzidos no espaço de nomes global
Opção 3
Um tanto controverso, mas se você estiver preparado para aguentar as advertências de ter uma std
classe 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
Tradeoffs;
- Não tente usar a classe herdada onde seria esperada uma base virtual (em particular, o destruidor não virtual). Não que isso deva ser um problema no caso - mas esteja ciente disso
- Novamente, o código muda
- Possíveis incompatibilidades de espaço para nome - tudo depende de como a classe do ponteiro é usada para começar
Opção 4
Coloque os ponteiros em uma nova classe e agregue as funções necessárias ao membro
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(); }
};
Tradeoffs;
- Um pouco extremo quando tudo o que você realmente deseja é "trocar" as implementações
auto_ptr
escopos (iestd::auto_ptr
), eles precisam ser ou o ponteiro inteligente pode ser obtido de algum outro espaço para nome?