Use boost :: swap to replace original pointers?

Based on pp. 8

Free functions

template<typename T> void swap(scoped_ptr<T>& a,scoped_ptr<T>& b)

      

This feature offers the preferred ways to exchange the contents of two pointers with a scope. This is preferred because swap (scoped1, scoped2) can be used generically (in a pattern) for many pointer types, including native pointers and third-party smart pointers. [2] scoped1.swap (scoped2) only works on smart pointers, not on original pointers and only on those that define the operation.

int* pA = new int(10);
int *pB = new int(20);

boost::swap(pA, pB); // Error: could not deduce template argument for 'boost::scoped_ptr<T> &' from 'int *'

      

Question How do I replace the original pointers with boost::swap

?

+3


source to share


2 answers


I don't understand why the other answers tell you not to use boost::swap

. The goal boost::swap

is to hide the business using std::swap; swap(x, y);

. This works great:

#include <boost/swap.hpp>

int main()
{
    int* pA = new int(10);
    int *pB = new int(20);

    boost::swap(pA, pB);

    delete pA;
    delete pB;
}

      

Obviously, if you haven't enabled it boost/swap.hpp

, it won't work. The way you use boost::swap

to exchange two things. You should always change two things on this form!

What you are reading just indicates that it boost::scoped_ptr

also provides overloading swap

inside the namespace boost

, so this works too:

#include <boost/scoped_ptr.hpp>

int main()
{    
    boost::scoped_ptr<int> pA(new int(20));
    boost::scoped_ptr<int> pB(new int(20));

    boost::swap(pA, pB);
}

      



But it should be clear that this won't work:

#include <boost/scoped_ptr.hpp>

int main()
{
    int* pA = new int(10);
    int *pB = new int(20);

    boost::swap(pA, pB);

    delete pA;
    delete pB;
}

      

Because I have boost/scoped_ptr.hpp

not provided (and is not responsible for) a general implementation boost::swap

. If you want to use it boost::swap

in general, you must include boost/swap.hpp

:

#include <boost/scoped_ptr.hpp>
#include <boost/swap.hpp>

int main()
{
    int* pA = new int(10);
    int *pB = new int(20);

    boost::scoped_ptr<int> pC(new int(20));
    boost::scoped_ptr<int> pD(new int(20));

    boost::swap(pA, pB);
    boost::swap(pC, pD);

    delete pA;
    delete pB;
}

      

Like this. If you have Boost to not do this, don't go back to using std::swap

.

+4


source


It boils down to the swap idiom, or how the swap should be implemented by user code. Recommended implementation swap

for a type T

in a namespace N

that has a set of elements m1

... mN

:

namespace N {
    void swap( T& lhs, T& rhs ) {
       using std::swap;
       swap( lhs.m1, rhs.m1 );
       ...
       swap( lhs.mN, rhs.mN );
    }
}

      



The idiom uses ADL (Argument Dependent Search). It first injects the definition std::swap

into scope, so that it is available if there is no better overload to replace a specific element. It then uses the unqualified free function swap

, knowing that if the type of Tn

any of the members mN

defines the swap of the free function, ADL will scop it and use the specialized swap

one instead std::swap

.

What the documentation says is what you shouldn't call ptr1.swap( ptr2 )

, but rather unqualified swap( ptr1, ptr2 )

, to swap any element, including objects scoped_ptr

, following the above idiom. That is, if you implement your swap as such, the function swap

should not change due to the change in the types of your members, including the pointer as a simple pointer or scoped_ptr

.

+4


source







All Articles