std :: map с ключом std :: weak_ptr

У меня есть вопрос об использовании std :: weak_ptr в качестве ключа для std :: map.

#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;
}

Вышеприведенная программа не собирается, и при попытке компиляции выдается много сообщений об ошибках, таких как:

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>          ]

Проблема возникает из-за следующей строки:

myMap[weakptr] = true;

Сообщения об ошибках, похоже, связаны с оператором<, Нужно ли определять оператора< для слабых_птрс? Какие именно операторы необходимо определить, чтобы использовать тип данных в качестве ключа для std :: map?

(Должен заметить, что я уже определил operator == в пространстве имен std. Также я планирую использовать weak_ptr для пользовательского типа класса, а не int.)

8

Решение

C ++ 11 предоставляет соответствующие механизмы для сравнения std::weak_ptrа именно: std::owner_less,

Это должно быть по умолчанию для карт и наборов. Если используемый вами компилятор C ++ испытывает трудности, попробуйте использовать std::owner_less если это доступно. Если он недоступен, вам необходимо предоставить механизм, аналогичный std::owner_less так что вы можете соответствующим образом сравнить std::weak_ptr объекты.

17

Другие решения

Третий аргумент шаблона для std :: map<> по умолчанию используется std :: less, который обычно просто вызывает оператор<() для ключа. Таким образом, вы можете любой определенный оператор<() для std :: weak_ptr<> (что, вероятно, является плохой идеей) или просто создайте функтор и укажите его в качестве третьего аргумента шаблона для std :: map<>.

Несмотря на это, я не уверен, может ли это действительно работать, потому что std :: map<> ожидает, что ключи будут неизменными, тогда как std :: weak_ptr<> может измениться в любое время (значение указателя может стать нулевым).

struct WeakPtrLess
{
template <typename T>
bool operator() (const std::weak_ptr<T>& l, const std::weak_ptr<T>& r) const
{
std::shared_ptr<T> sl = l.lock();
std::shared_ptr<T> sr = r.lock();

return sl.get() < sr.get();
}
};

Используйте это на свой страх и риск. (Или каково бы ни было выражение)

0

По вопросам рекламы [email protected]