1. 導入:なぜstd::owner_lessが必要なのか
C++の実務において、std::shared_ptrをstd::mapのキーやstd::setの要素として使いたい場面は少なくありません。しかし、何も考えずにstd::shared_ptrをキーにすると、期待通りの挙動にならない可能性があります。std::shared_ptrのデフォルトの比較演算子(operator<)は「ポインタが指すアドレス値」を比較しますが、これでは「同じオブジェクトを所有していても、異なるshared_ptrインスタンスであれば別物」とみなされてしまうからです。これを解決し、所有権の元となる「制御ブロック」に基づいて比較を行うのがstd::owner_lessです。
2. 基礎知識:制御ブロックとは何か
std::shared_ptrは、実際のオブジェクトへのポインタとは別に、参照カウントなどを保持する「制御ブロック」を持っています。複数のstd::shared_ptrが同じオブジェクトを共有している場合、それらは同じ制御ブロックを共有しています。std::owner_lessは、この制御ブロックのアドレスを基準に比較を行います。これにより、異なるshared_ptrインスタンスであっても、同じリソースを所有していれば「同一」として扱えるようになります。
3. 実装:std::mapでの利用手順
std::mapやstd::setはデフォルトでstd::lessを使用しますが、これをstd::owner_lessに置き換える必要があります。テンプレート引数にstd::shared_ptrを指定することで、コンテナ内部での順序付けがアドレス値ではなく所有権ベースで行われるようになります。
4. サンプルプログラム
以下のコードは、同じオブジェクトを指す異なるstd::shared_ptrをmapのキーとして使用する例です。
include
include
include
コメント