You cannot do this during references, as they should never be NULL. There are basically three options, one using a pointer, the others using value semantics.
-
With a pointer (note: this requires that the resource doesn’t get destructed while the caller has a pointer to it; also make sure the caller knows it doesn’t need to delete the object):
SomeResource* SomeClass::getSomething(std::string name) { std::map<std::string, SomeResource>::iterator it = content_.find(name); if (it != content_.end()) return &(*it); return NULL; }
-
Using
std::pair
with abool
to indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):std::pair<SomeResource, bool> SomeClass::getSomething(std::string name) { std::map<std::string, SomeResource>::iterator it = content_.find(name); if (it != content_.end()) return std::make_pair(*it, true); return std::make_pair(SomeResource(), false); }
-
Using
boost::optional
:boost::optional<SomeResource> SomeClass::getSomething(std::string name) { std::map<std::string, SomeResource>::iterator it = content_.find(name); if (it != content_.end()) return *it; return boost::optional<SomeResource>(); }
If you want value semantics and have the ability to use Boost, I’d recommend option three. The primary advantage of boost::optional
over std::pair
is that an unitialized boost::optional
value doesn’t construct the type its encapsulating. This means it works for types that have no default constructor and saves time/memory for types with a non-trivial default constructor.
I also modified your example so you’re not searching the map twice (by reusing the iterator).