Skip to main content
GameDev.net gamedev.net
🔒 Locked

auto_ptr + STL containers

Started by deffer Jul 10, 2006 at 4:38 PM 14 replies 6.7k views
Original Post
deffer
deffer
Can I use auto_ptr with STL containers? class MyClass; std::map > Yes, I know that I cannot do this with std::vector, because it copies elements around. But std::map, std::list, etc. - do they have any cons?
SiCrane
SiCrane
No. Don't do this. It may compile, but the semantics are significantly screwy that simple things like just iterating through the container may wipe all the elements.
deffer
deffer
Ok, I'll just use boost::shared_ptr, as I planned.
Agony
Agony
Quote:
Original post by deffer
Can I use auto_ptr with STL containers?

class MyClass;
std::map >

Yes, I know that I cannot do this with std::vector, because it copies elements around. But std::map, std::list, etc. - do they have any cons?

More or less all std containers copy at some point or another. For some containers this is only when you insert an item (a copy is made of the item you tell it to insert, and this copy is inserted, not the original item), but it's still at least one copy for each item you insert.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas nly, and not for things themselves." - John Locke o
deffer
deffer
Quote:
Original post by Sharlin
You might want to check out boost::ptr_containers while you're at it.


Seems nice, but I see that I don't have necessary headers in my boost distribution. Is it a fresh new library?
Fruny
Fruny
Quote:
Original post by deffer
Seems nice, but I see that I don't have necessary headers in my boost distribution. Is it a fresh new library?


It got added last year in 1.33.0.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Zahlman
Zahlman
I've tried to trace through the logic of this in the past and failed: when a vector copies for resizing, it's copying to the new container space, so it shouldn't matter if the old pointers no longer have ownership, since the old space is about to disappear anyway, right? What's the problem?
deffer
deffer
Const correctness of copying auto_ptr?
Fruny
Fruny
Quote:
Original post by deffer
Const correctness of copying auto_ptr?


You can't copy a const auto_ptr: the copy constructor is defined as taking a non-const reference.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
SiCrane
SiCrane
The real danger of containers of auto_ptrs isn't in the actual container end of things. The real problem is that many algorithms that operate on iterator ranges will make temporary copies of elements in the iterator range. Ex: std::sort() implementations almost always involves creating a copy of the pivot element. Pass begin(), end() of a container of auto_ptrs to std::sort() and boom, a third of your elements disappear into the ether. (And your sort gets all wonky since elements are actually getting modified, but that's a minor detail when dealing with the fact that your data is getting destroyed.)

Photonman
Photonman
Well, I can give you Stoustrup's explanation from TC++PL (pg. 368):

The purpose of auto_ptr_ref is to implement the destructive copy semantics for ordinary auto_ptrs while making it impossible to copy a const auto_ptr....
...
Note that auto_ptr's destructive copy semantics means that it does not meet the requirements for elements of a standard container or for standard algorithms such as sort().

That really is a good book.
______Stranger things have happened...The Following Sentence is True. The Above Sentence is False.
Nitage
Nitage
Quote:
Original post by Fruny
Quote:
Original post by deffer
Const correctness of copying auto_ptr?


You can't copy a const auto_ptr: the copy constructor is defined as taking a non-const reference.


I think he meant that since push_back() and insert() take const references, so it is the const correctness of auto_ptr that prevents auto_ptr from being used with the standard containers.

The following code fails to compile with errors about no copy constructor being available:
int main(){    std::vector< std::auto_ptr<int> > vect;    std::auto_ptr<int> autoPtr;    vect.push_back( autoPtr );}


[Edited by - Nitage on July 11, 2006 5:17:10 AM]
Deyja
Deyja
The problem, as someone already said, isn't putting auto_ptrs into the container.

It's getting them back out again.
Nitage
Nitage
Quote:
Original post by Deyja
The problem, as someone already said, isn't putting auto_ptrs into the container.


Interesting point of view, seeing as it's impossible to insert auto_ptrs into a standard container.
markr
markr
auto_ptrs can only really be used in cases where no implicit copies will happen. This means:

- On the stack
- As members of classes which aren't copyable (or implement their own different copying semantics)

And they're very useful in this role. But don't use them for anything else.

Mark

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.