We are testing a library under C++11 (i.e., -std=c++11). The library uses auto_ptr and this pattern:

Foo* GetFoo()
    autoptr<Foo> ptr(new Foo);

    // Initialize Foo

    // Now configure remaining attributes

    return ptr.release();

C++11 deprecated auto_ptr, so we want to move away from it.

However, the code supports both C++03 and C++11, so its not a simple as yanking auto_ptr. It's also worth mentioning the library has no external dependencies. It uses C++03; and does not use Autotools, Cmake, Boost, ...

How should we handle the design changes to move away from auto_ptr for C++11 while retaining compatibility with C++03?

  • Are any of the auto_ptr scoped (i.e. std::auto_ptr), do they need to be or can the smart pointer be obtained from some other namespace? – Niall Jul 29 '15 at 8:59
  • As an aside, you may want to fold Foo::Initialize into Foo::Foo. – MSalters Jul 29 '15 at 9:42
  • 1
    @MSalters - yeah, that has always been one of those things I have felt mildly uncomfortable about. The library was designed in the 1990s, and I think the design was similar to MFC. That is, there was lower level C++ construction, and then a "higher level" object construction. I think the feature was used as a tradeoff so classes don't have 6 or 12 different constructors. (At this point, what I have done is gone through and ensured the member variables of POD types are initialized to sane defaults in the C++ constructors). – jww Jul 29 '15 at 10:05

In most respects the std::unique_ptr was made to be drop in (but safer) replacement for std::auto_ptr, so there should be very few (if any) code changes required other than (as you ask) directing the code to use either unique_ptr or auto_ptr.

There a few ways to do this (and each comes with its own list tradeoffs) below. Given the code sample provided, I would favour either of the first two options.

Option 1

#if __cplusplus >= 201103L
template <typename T>
using auto_ptr = std::unique_ptr<T>;
using std::auto_ptr;


  • You introduce the auto_ptr name into the global namespace; you can mitigate this by defining it is your own "private" namespace
  • Once migrate to C++17 (I believe auto_ptr will be completely removed) you can more easily search and replace

Option 2

template <typename T>
struct my_ptr {
    #if __cplusplus >= 201103L
    typedef std::unique_ptr<T> ptr;
    typedef std::auto_ptr<T> ptr;


  • Probably more cumbersome to work with, all the current auto_ptr need to changed in the code to something like my_ptr<T>::ptr
  • Better safety the names are not being introduced into the global namespace

Option 3

Somewhat controversial, but if you are prepared to put up with the caveats of having a std class as a base

#if __cplusplus >= 201103L
template <typename T>
using my_ptr = std::unique_ptr<T>;
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) {}


  • Don't try to use the inherited class where a virtual base (in particular w.r.t. the non-virtual destructor) would be expected. Not that this should be an issue in the case - but be aware of it
  • Again, code changes
  • Potential namespace mismatches - it all depends on how the pointer class is used to begin with

Option 4

Wrap the pointers in a new class and aggregate the required functions to the member

template <typename T>
class my_ptr { // could even use auto_ptr name?
  #if __cplusplus >= 201103L
  std::unique_ptr<T> ptr_;
  std::auto_ptr<T> ptr_;

  // implement functions required...
  T* release() { return ptr_.release(); }


  • A little extreme when all you really want is to "swap" the implementations out
  • Very good answer. I actually researched it a bit, and you hit at least three of the tests I tried. (What you lack is the OS X and Clang specific stuff. OS X is a bear because it still uses TR1 namespace for C++03 at times, and you have to include things using this method: No type named 'unique_ptr' in namespace 'std' when compiling under LLVM/Clang). – jww Jul 29 '15 at 10:07
  • @jww. I'm on OS X (XCode 6.4 and Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)) and have no issues with the C++03/11 mix other than the tr1 namespace no longer being there (I do use libc++ and not libstdc++). I know tr1 was non-normative, but I can't find anywhere in the draft (here) that the files had to be <tr1/...> at all, infact it mentions just being in the header <memory> etc. file just in the tr1 namespace. – Niall Jul 29 '15 at 11:17
  • @jww. I guess that given a particular mix of compiler, library and target device - you may need to do a few more hand stands. Else, on OS X, consider moving to clang and libc++. Frankly I consider the libc++ to be the new "native" C++ library to OS X - I would default to that. I have no way to support these claims other that the history of the clang/Apple relationship and that the GCC tools on OS X seem out of date (library) or just removed (as far as I know GCC is a thin stub to clang anyway). – Niall Jul 29 '15 at 11:24
  • "Else, on OS X, consider moving to clang and libc++..." - yeah, I kind of agree with you. However, we would like to let the users make that choice, and not force it upon them. (They implicitly make the choice when they specify (or lack) CXX=...). – jww Jul 29 '15 at 11:27
  • Here's the case that is causing me so much trouble on OS X 10.7 and 10.8: c++ -v -std=c++11 -x c++ - < /dev/null. I grep'd the include directories that were dumped, and they do not include unique_ptr. – jww Jul 29 '15 at 11:30

Option 5: Direct alias.

#if __cplusplus >= 201103L
template<typename T> 
using MyPtr = std::unique_ptr<T>;
#define MyPtr std::auto_ptr


  1. For newer language versions, AKA C++11 and later, your alias type maps to the correct smart pointer. Any user code that actually depends on APIs specific to std::auto_ptr will get flagged by the compiler, which is the ultimate guarantee that it'll really be fixed.

  2. In Legacy c++03 mode the type alias is a macro. This is gross, but the resulting syntax MyPtr<T> will be identical to the C++11 case throughout the rest of the code.

  3. You have to find and change all your auto_ptr variables to MyPtrin order to set this up.

  • 1
    It's very unclear what this is referencing (and, as phrased, it isn't a question at all). – autophage Jan 16 at 19:53
  • @autophage I believe its an answer... so probably not a question. – Kain0_0 Jan 17 at 0:35

protected by gnat Jan 16 at 21:23

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.