tags:

views:

121

answers:

2

I was going through the auto_ptr documentation on this link auto_ptr There is something which i could not fully understand why is it done. In the interface section there are two declarations for its copy constructor

1)

auto_ptr(auto_ptr<X>&) throw (); 

2)

template <class Y> 
     auto_ptr(auto_ptr<Y>&) throw(); 

What purpose is this for.

+5  A: 

It's there in case you can implicitly convert the pointers:

struct base {};
struct derived : base {};

std::auto_ptr<derived> d(new derived);
std::auto_ptr<base> b(d); // converts 

Also, you didn't ask but you'll notice the copy-constructor is non-const. This is because the auto_ptr will take ownership of the pointer. In the sample above, after b is constructed, d holds on to nothing. This makes auto_ptr unsuitable for use in containers, because it can't be copied around.

C++0x ditches auto_ptr and makes one called unique_ptr. This pointer has the same goals, but accomplishes them correctly because of move-semantics. That is, while it cannot be copied, it can "move" ownership:

std::unique_ptr<derived> d(new derived);

std::unique_ptr<base> b(d); // nope, cannot be copied
std::unique_ptr<base> b(std::move(d)); // but can be moved

This makes unique_ptr suitable for use in containers, because they no longer copy their values, they move them.

GMan
Specifically, the *second* constructor is there for implicit conversion (which technically makes it not a copy constructor).
Travis Gockel
The first _is_ a valid copy constructor. A copy constructor can take either a reference or a const reference to the class type. Either form is a valid copy constructor.
Charles Bailey
GMan
@Charles Bailey, it's valid as a copy constructor, technically. But it's quite surprising for something called a 'copy constructor' to modify the thing being copied. It's not really a copy constructor IMHO if that's what it's doing. It's all you __can__ do in non-C++0x C++ though.
Omnifarious
Yogesh Arora
GMan
thanks, now i think i have auto_ptr fully figured out
Yogesh Arora
@Yogesh: Indeed. While it's still useful in some situations, it's definitely a dumber smart pointer. C++0x's `unique_ptr`, which can handle normal types as well as arrays, will definitely be a usable smart pointer.
GMan
@Gman: I agree with that, but i just wanted to fully understand it shortcomings, and how it was designed, only then i can better understand the reason behind the changes in C++0x. I want to get my basics right
Yogesh Arora
@Gman - Shouldn't you have written `struct derived : public base {};`
R Samuel Klatchko
@R Samuel: structs inherit publicly by default. It's the only other difference that have with classes, the other being structs default to `public:` while classes are `private:`.
GMan
@R Samuel: Oh, but yes I do need to at least inherit, don't I? :) Thanks, heh.
GMan
+4  A: 

The first one is a copy constructor, then second one is a templated constructor from auto_ptr with other template parameters.

The implementation has to provide a non-template copy constructor if it doesn't want the compiler generated one. This is because a templated constructor that could be used as a copy constructor doesn't suppress the compiler generate one and the compiler generated one would always be a better match for copy construction by virtue of not being a template.

Charles Bailey
I don't think the OP is asking why a copy constructor is needed. I think the OP is asking why there are _two_ things that both look like copy constructors.
Omnifarious
@Omnifarious: And that's exactly what my answer addresses, why the non-template version must be supplied even if the template version appears to cover all options.
Charles Bailey