首页 文章

std :: map with std :: weak_ptr key

提问于
浏览
8

我有一个关于使用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;

错误消息似乎与operator <有关 . 我是否需要为weak_ptrs定义operator <?究竟是什么运算符需要定义才能使用数据类型作为std :: map的键?

(我应该注意到我已经在std命名空间中定义了operator == . 另外,我计划将weak_ptr用于自定义类类型而不是int . )

2 回答

  • 19

    C 11提供了适当的机制来比较 std::weak_ptr ,即: std::owner_less .

    这应该是 Map 和集合的默认值 . 如果您使用的C编译器很难,请尝试使用 std::owner_less (如果可用) . 如果它不可用,您将需要提供与 std::owner_less 类似的机制,以便您可以适当地比较 std::weak_ptr 对象 .

  • -1

    std :: map <>的第三个模板参数默认为std :: less,它通常只为Key调用operator <() . 因此,您可以为std :: weak_ptr <>定义operator <()(这可能是一个坏主意),或者只是创建一个仿函数并将其作为std :: map <>的第三个模板参数提供 .

    即便如此,我不确定这是否可以实际工作,因为std :: map <>期望键是不可变的,而std :: weak_ptr <>可以随时改变(指针值可以变为null) .

    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();
      }
    };
    

    使用它自担风险 . (或者无论表达是什么)

相关问题