If my class SomeType has a method that returns a element from the map (using the key) say
std::unique_ptr<OtherType> get_othertype(std::string name)
{
return otMap.find(name);
}
that would enure the caller would recieve a pointer to the one in the map rather than a copy? Is it ok to do this, or would it try and call the copy constructor (and fail as it has been removed) because it is being returned?
Assuming I must use unique_ptr as my map items.
UPDATE::
After trying to implement the code, it seems that unique_ptr and std:map/:pair dont work together in gcc 4.4.4, pair just didnt like unique_ptr as a type parameter. (see Can't create map of MoveConstructibles).
I changed the ptr to std::shared_ptr and it all worked.
I suppose I can use the same code with the shared pointer?
The model of unique_ptr
is transfer of ownership. If you return a unique_ptr
to an object from a function, then no other unique_ptr
in the system can possibly refer to the same object.
Is that what you want? I highly doubt it. Of course, you could simply return a raw pointer:
OtherType* get_othertype(const std::string& name)
{
return otMap.find(name)->second.get();
}
Thus, the client has access to the object, but the map still owns it.
The above solution is rather brittle in case there is no entry found under the name. A better solution would be to either throw an exception or return a null pointer in that case:
#include <stdexcept>
OtherType* get_othertype(const std::string& name)
{
auto it = otMap.find(name);
if (it == otMap.end()) throw std::invalid_argument("entry not found");
return it->second.get();
}
OtherType* get_othertype(const std::string& name)
{
auto it = otMap.find(name);
return (it == otMap.end()) ? 0 : it->second.get();
}
And just for completeness, here is Anthony's suggestion of returning a reference:
OtherType& get_othertype(const std::string& name)
{
auto it = otMap.find(name);
if (it == otMap.end()) throw std::invalid_argument("entry not found");
return *(it->second);
}
And here is how you return a reference to the unique_ptr
inside the map, but let's make that a reference to const, so the client does not accidentally modify the original:
unique_ptr<OtherType> const& get_othertype(const std::string& name)
{
auto it = otMap.find(name);
if (it == otMap.end()) throw std::invalid_argument("entry not found");
return it->second;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With