How can I use a std::map with std::weak_ptr as key?

c++, dictionary, stdmap, weak-ptr, weak-references

Solution

C++11 provides appropriate mechanisms for comparisons of `std::weak_ptr`, namely: `std::owner_less`.

This should be the default for maps and sets. If the C++ compiler you are using is having a hard time, try using `std::owner_less` if it is available. If it is not available, you will need to provide a similar mechanism as `std::owner_less` so you can appropriately compare `std::weak_ptr` objects.

Problem

How can I use `std::weak_ptr` as key for a `std::map` as shown in the following code? ``` #include <map> #include <memory> int main() { std::map< std::weak_ptr<int>, bool > myMap; std::shared_ptr<int> sharedptr(new int(5)); std::weak_ptr<int> weakptr = sharedptr; myMap[weakptr] = true; return 0; } ``` The above program doesn't build and trying to compile it gives many error messages such as: ``` 1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xfunctional(125): error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::tr1::weak_ptr<_Ty>' 1> with 1> [ 1> _Ty=int 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xtree(1885) : see declaration of 'std::operator <' 1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xfunctional(124) : while compiling class template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const' 1> with 1> [ 1> _Ty=std::tr1::weak_ptr<int> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\map(71) : see reference to class template instantiation 'std::less<_Ty>' being compiled 1> with 1> [ 1> _Ty=std::tr1::weak_ptr<int> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xtree(451) : see reference to class template instantiation 'std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,_Mfl>' being compiled 1> with 1> [ 1> _Kty=std::tr1::weak_ptr<int>, 1> _Ty=bool, 1> _Pr=std::less<std::tr1::weak_ptr<int>>, 1> _Alloc=std::allocator<std::pair<const std::tr1::weak_ptr<int>,bool>>, 1> _Mfl=false 1> ] ``` The problem occurs due to the following line: ``` myMap[weakptr] = true; ``` The error messages seem to be related to `operator<`. Do I need to define `operator<` for `weak_ptr`? Exactly, what operators need to be defined in order to use a data type as a key for a `std::map`? (I should note that I have already defined `operator==` in the `std` namespace. Also, I plan to use a `weak_ptr` to a custom class type and not an `int`.)

Original source