c++c++11unique-ptrauto-ptr

"using" (or other mechanism) to swap in unique_ptr for auto_ptr in C++11?


I'm catching a compile warning under Cygwin with -std=c++11:

cryptlib.cpp: In member function ‘virtual size_t PK_Signer::SignMessage(RandomNumberGenerator&, const byte*, size_t, byte*) const’:
cryptlib.cpp:770:41: warning: ‘auto_ptr’ is deprecated (declared at /usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/backward/auto_ptr.h:87) [-Wdeprecated-declarations]
std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
                                       ^

I tried adding:

#if defined(MYLIB_CXX11)
using auto_ptr = std::unique_ptr;
#else
using std::auto_ptr;
#endif

auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));

But it resulted in the following, even with <memory> included.

$ make cryptlib.o 
c++ -std=c++11 -DNDEBUG -g2 -O3 -fPIC -march=native -DCRYPTOPP_DISABLE_ASM -Wall -Wextra -pipe -c cryptlib.cpp
cryptlib.cpp:770:27: error: no type named 'unique_ptr' in namespace 'std'
    using auto_ptr = std::unique_ptr;
                     ~~~~~^

I also tried variations of the following:

#if defined(MYLIB_CXX11)
typedef std::unique_ptr<T> local_ptr<T>;
#else
typedef std::auto_ptr local_ptr;
#endif

I can't make a clean cut-over to unique_ptr because its a C++03 library, and C++03 lacks unique_ptr. And I can't allow the dirty compile to continue under C++11 because clean compiles are a security gate, and governance will not allow the library to pass. (And warning tricks are out of the question because this is should be simple, low hanging fruit. Warning tricks include disabling the warning).

Is it possible to use "using" to swap in unique_ptr? Or is there some other mechanism?


Solution

  • Understanding that the code is under your control and can be recompiled with or with out C++11 support, an alias can be created for the smart pointer required (either std::unique_ptr or std::auto_ptr).

    template <typename T>
    struct local_ptr {
        #if defined(MYLIB_CXX11)
        typedef std::unique_ptr<T> ptr;
        #else
        typedef std::auto_ptr<T> ptr;
        #endif
    };
    

    Then used in the client code as such;

    local_ptr< PK_MessageAccumulator>::ptr managed = //...
    

    The syntax is more awkward than desired, but this is to accommodate the requirement to support C++03.

    In all cases, the long term solution is to factor out the use of auto_ptr or silence the deprecated warnings.