19

次のコードに示すように、std::weak_ptra のキーとしてどのように使用できますか?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<。を定義する必要がありますoperator<weak_ptr? 正確には、データ型を ? のキーとして使用するには、どの演算子を定義する必要がありstd::mapますか?

operator==(名前空間で既に定義していることに注意してください。また、 ではなくカスタム クラス型にstdを使用する予定です。)weak_ptrint

4

2 に答える 2

30

C ++ 11はstd::weak_ptr、以下を比較するための適切なメカニズムを提供しますstd::owner_less

これは、マップとセットのデフォルトである必要があります。使用しているC++コンパイラが問題を抱えている場合は、std::owner_less使用可能な場合は使用してみてください。std::owner_less利用できない場合は、オブジェクトを適切に比較できるように、同様のメカニズムを提供する必要がありstd::weak_ptrます。

于 2012-10-13T18:36:29.937 に答える
7

Jody Hagins' answerで説明されているように、 as キーstd::owner_lessを使用する場合は、連想コンテナーの比較関数オブジェクトとして使用する必要があります。std::weak_ptrコードに次の完全なソリューションを提供することで、その答えを拡張したいと思います。

int main() {
    std::map<std::weak_ptr<int>, bool, std::owner_less<std::weak_ptr<int>>> myMap;

    std::shared_ptr<int> sharedptr(new int(5));
    std::weak_ptr<int> weakptr = sharedptr;

    myMap[weakptr] = true;

    return 0;
}

C++17以降、 のテンプレート パラメータを省略できるためowner_less、次のようにコードが短くなります。

std::map<std::weak_ptr<int>, bool, std::owner_less<>> myMap;

また、weak_ptrの代わりに をカスタム クラスに使用する場合は、Coliru のこのサンプル コードに示されているように、 をクラスの名前にint置き換えるだけです。int

一般に、(カスタム) キー タイプに適切な比較関数 (または のオーバーロード) を提供することを除けば、 に対してoperator<何もする必要はありませんstd::mapoperator==キー タイプのオーバーロードは必要ありません。

于 2019-09-17T08:36:35.090 に答える