1

auto_ptr on wikipedia said that "an auto_ptr containing an STL container may be used to prevent further modification of the container.". It used the following example:

auto_ptr<vector<ContainedType> > open_vec(new vector<ContainedType>);

open_vec->push_back(5);
open_vec->push_back(3);

// Transfers control, but now the vector cannot be changed:
auto_ptr<const vector<ContainedType> > closed_vec(open_vec); 

// closed_vec->push_back(8); // Can no longer modify

If I uncomment the last line, g++ will report an error as

t05.cpp:24: error: passing ‘const std::vector<int, std::allocator<int> >’ 
as ‘this’   argument of ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) 
[with _Tp = int, _Alloc = std::allocator<int>]’ discards qualifiers

I am curious why after transferring the ownership of this vector, it can no longer be modified?

Thanks a lot!

curiousguy
  • 8,038
  • 2
  • 40
  • 58
icephere
  • 1,415
  • 2
  • 9
  • 5

2 Answers2

4

The closed_vec pointer holds the type const vector<ContainedType>. Because the type is const, you can't call any methods on it that aren't also defined as const (which means they don't change internal data). Naturally push_back is non-const, as it changes the vector, so you can't call it on a const pointer. It doesn't really have anything to do with auto_ptr, you could accomplish the same with regular pointers:

vector<ContainedType>* open_vec = new vector<ContainedType>();
open_vec->push_back(5);
open_vec->push_back(3);

const vector<ContainedType>* closed_vec = open_vec;
closed_vec->push_back(8); // Fails
Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
  • Thanks a lot! :) I overlooked the "const" in closed_vec. – icephere Jun 15 '10 at 20:02
  • 3
    It _does_ have something to do with auto_ptr. With regular pointers, the old non-const pointer could still be used to modify the container. The non-const auto_ptr will be NULL after the ownership transfer. – MSalters Jun 16 '10 at 09:51
1

You can't modify the vector because closed_vec is a pointer-to-const, so the compiler won't let you modify the pointer (but you could still move the pointer). To allow modification of the vector, declare closed_vec as

auto_ptr<vector<ContainedType> > closed_vec(open_vec); // no const anymore
closed_vec->push_back(8); // this now works

If you had declared the pointer as

const auto_ptr<vector<ContainedType> > closed_vec(open_vec);

on the other hand, you would be able to change the pointee, but not move the pointer.

George Steel
  • 697
  • 5
  • 7