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
?
source to share
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
.
source to share
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
.
source to share