В большинстве отношениях std::unique_ptr
было сделано , чтобы быть падение (но безопаснее) замены для std::auto_ptr
, так что должно быть очень мало (если таковые имеются) изменения кода требуется , кроме (как вы спрашиваете) направлять код для использования либо unique_ptr
или auto_ptr
.
Есть несколько способов сделать это (и каждый из них имеет свой собственный компромисс со списком) ниже. Учитывая предоставленный пример кода, я бы предпочел любой из первых двух вариантов .
Опция 1
#if __cplusplus >= 201103L
template <typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif
Компромисс;
- Вы вводите
auto_ptr
имя в глобальное пространство имен; Вы можете смягчить это, определив, что это ваше собственное "личное" пространство имен
- После перехода на C ++ 17 (я думаю, что
auto_ptr
он будет полностью удален), вам будет проще искать и заменять
Вариант 2
template <typename T>
struct my_ptr {
#if __cplusplus >= 201103L
typedef std::unique_ptr<T> ptr;
#else
typedef std::auto_ptr<T> ptr;
#endif
};
Компромисс;
- Наверное, с этим труднее работать, все текущие изменения
auto_ptr
должны быть изменены в коде на что-то вродеmy_ptr<T>::ptr
- Для большей безопасности имена не вводятся в глобальное пространство имен
Вариант 3
Несколько спорны, но если вы готовы мириться с предостережениями , имеющим std
класс в качестве основы
#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
Компромисс;
- Не пытайтесь использовать унаследованный класс, где ожидается виртуальная база (в частности, не виртуальный деструктор). Не то чтобы это должно было быть проблемой в деле - но имейте это в виду
- Опять же, изменения кода
- Потенциальное несоответствие пространства имен - все зависит от того, как класс указателя используется для начала
Вариант 4
Оберните указатели в новый класс и объедините необходимые функции для члена
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(); }
};
Компромисс;
- Немного экстрима, когда все, что вам действительно нужно, это «поменять» реализации
auto_ptr
областей (то естьstd::auto_ptr
), они должны быть или умный указатель может быть получен из некоторого другого пространства имен?