sazr
sazr

Reputation: 25938

Why Does Getting/Setting Auto_Ptr Cause This Compiler Error

I have a map of auto_ptr's and I am simply trying to set and get map elements but its producing compiler errors. I don't understand what the compiler error means and whats going wrong?

Get compiler error:

[Error] passing 'const std::auto_ptr' as 'this' argument of 'std::auto_ptr<_Tp>::operator std::auto_ptr_ref<_Tp1>() [with _Tp1 = int; _Tp = int]' discards qualifiers [-fpermissive]

Set compiler error:

[Error] no match for 'operator=' (operand types are 'std::map, std::auto_ptr >::mapped_type {aka std::auto_ptr}' and 'int*')

Also I've heard it's not advised to use auto_ptr's in standard c++ library collections (list, vector, map). What kind of smart pointer should I use in the below code?

std::map <std::string, std::auto_ptr<int> > myMap;

// Throws compiler error
std::auto_ptr <int> a = myMap["a"];
// Also throws compiler error
myMap["a"] = new int; 

Upvotes: 0

Views: 457

Answers (1)

M.M
M.M

Reputation: 141613

Firstly, don't use auto_ptr. It has broken semantics and is deprecated. The proper pointer for single-ownership semantics is unique_ptr.

You can have:

std::map<std::string, std::unique_ptr<int> > myMap;

Now, when you write myMap["a"], an entry in the map will be created for "a", and this returns a reference to that. The entry created is std::unique_ptr<int>{} which is a "null" pointer.

You can make this point somewhere, however you use the member function reset for that, not the assignment operator:

myMap["a"].reset( new int{5} );

or alternatively, since C++14,

myMap["a"] = std::make_unique<int>(5);

Your other doesn't quite make sense, if you want single ownership. You can either look at the raw pointer value, or you can take ownership. To take ownership:

std::unique_ptr<int> new_owner = std::move(myMap["a"]);

which will leave the existing map entry as a "null" pointer again, and new_owner has ownership.

If you just want to do something with the raw pointer in the map then you can use get() to get that pointer, or use the dereference operator directly on the unique_ptr:

myMap["a"].reset( new int{5} );
int *raw = myMap["a"].get();
*myMap["a"] = 6;

Upvotes: 5

Related Questions