Sign in to follow this  

boost::scoped_ptr and swap

This topic is 3489 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was reading through the documentation for boost::scoped_ptr and saw the definition for the following free function: template <typename T> void swap(scoped_ptr<T>& a, scaped_ptr<T>& b); They said it can be used to swap two boost::scoped_ptrs as well as a boost::scoped_ptr with a raw pointer. But I don't see how the above implementation can achieve that because: (1) boost::scoped_ptr's constructor is explicit (2) If boost::scoped_ptr's constructor wasn't explicit, it would imply creation of a temporary. The problem is that once the temporary is created it would be bound a non-const reference -- which is illegal. How can they achieve this behavior without defining something like the following in addition to the above free function: template <typename T> void swap(scoped_ptr<T>& a, T*& b); template <typename T> void swap(T*& a, scaped_ptr<T>& b); Did they additionally implement the above two functions and not document it, or did they do something more tricky?

Share this post


Link to post
Share on other sites
Where did it say that it can be used to swap a scoped_ptr with a raw pointer? That's reasonable functionality, but AFAIK it's not the case.

Share this post


Link to post
Share on other sites
I actually posted, but I just reread what you asked. I agree that it doesn't make any sense that it can do this. Taking a quick look at the implementation, it doesn't appear that it can. I don't have the time to try a test case right now, though.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Where did it say that it can be used to swap a scoped_ptr with a raw pointer? That's reasonable functionality, but AFAIK it's not the case.


It says so in the book "Beyond the C++ Standard Library: An Introduction to Boost". It may be worth noting that the version of Boost that the book covers is a few minor numbers behind the current version, but I don't think that should matter that much.

Share this post


Link to post
Share on other sites
Well...
#include <boost/scoped_ptr.hpp>
int main(int argc, _TCHAR* argv[])
{
boost::scoped_ptr<int> a(new int);
int* b(new int);
swap(a,b);
}

Produces:
.\teststuff.cpp(15) : error C2784: 'void boost::swap(boost::scoped_ptr<T> &,boost::scoped_ptr<T> &)' : 
could not deduce template argument for 'boost::scoped_ptr<T> &'
from 'int *'

I'm not familiar with the book you mentioned, so I can't speak to it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Well...
#include <boost/scoped_ptr.hpp>
int main(int argc, _TCHAR* argv[])
{
boost::scoped_ptr<int> a(new int);
int* b(new int);
swap(a,b);
}

Produces:
.\teststuff.cpp(15) : error C2784: 'void boost::swap(boost::scoped_ptr<T> &,boost::scoped_ptr<T> &)' : 
could not deduce template argument for 'boost::scoped_ptr<T> &'
from 'int *'

I'm not familiar with the book you mentioned, so I can't speak to it.


I guess your code snippet proves it. Additionally I didn't know you could write int* b(new int). Is that some sort of POD constructor syntax that was added to make generics easier to code?

My original confusion may have something to do with unclear wording:

Quote:

Excerpt from: "Beyond the C++ Standard Library: An Introduction to Boost" p.8

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

The function offers the preferred means by which to exchange the contents of two scoped pointers. It is preferable because swap(scoped1, scoped2) can be applied generically (in templated code) to many pointer types, including raw pointers and third party smart pointers.2

2. You can create your own free swap function for third-party smart pointers that weren't smart enough to provide their own.

Share this post


Link to post
Share on other sites
Quote:
Original post by fpsgamer
I guess your code snippet proves it. Additionally I didn't know you could write int* b(new int). Is that some sort of POD constructor syntax that was added to make generics easier to code?

It is identical in every way to int* b = new int;. It was added, I imagine, more as a way to normalize the syntax of construction and initialization than to make generics easier (though of course it does do that as well). It also dovetails nicely with explicit casting: int a=3,b=4; float f=float(a)/b;

Quote:
My original confusion may have something to do with unclear wording:

Quote:

Excerpt from: "Beyond the C++ Standard Library: An Introduction to Boost" p.8

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

The function offers the preferred means by which to exchange the contents of two scoped pointers. It is preferable because swap(scoped1, scoped2) can be applied generically (in templated code) to many pointer types, including raw pointers and third party smart pointers.2

2. You can create your own free swap function for third-party smart pointers that weren't smart enough to provide their own.

I assume that what they meant there was that swap() can be overloaded for any pointer type you like, to normalize the interface involved (useful for things like smart pointers, which tend to be grouchy about construction and destruction). Indeed, the implementation of std::swap already covers raw pointers. However, that doesn't allow you to swap two elements that have different type; offhand, all the swap() overloads I can think of require that both arguments have the same type.

Share this post


Link to post
Share on other sites
Quote:
Original post by fpsgamer
I didn't know you could write int* b(new int). Is that some sort of POD constructor syntax that was added to make generics easier to code?


I think the main motivation was to allow you to give default values to arguments in template functions:


template <class T>
void func(const T &val = T()) {
//...
}



I think doing this is impossible without this feature (what kind of default value is suitable for both an int and an std::string?).

Share this post


Link to post
Share on other sites

This topic is 3489 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this