最終更新日時:
が更新

履歴 編集

function
<memory>

std::shared_ptr::owner_before(C++11)

template <class U>
bool owner_before(const shared_ptr<U>& b) const;          // (1) C++11

template <class U>
bool owner_before(const shared_ptr<U>& b) const noexcept; // (1) C++17

template <class U>
bool owner_before(const weak_ptr<U>& b) const;            // (2) C++11

template <class U>
bool owner_before(const weak_ptr<U>& b) const noexcept;   // (2) C++17

概要

所有権ベースでの小なり比較を行う。

戻り値

*thisが持つリソースと、bが持つリソースを、所有権ベースで小なり比較し、*thisが小さければtrue、そうでなければfalseを返す。

備考

shared_ptrにおいて、a < bは以下の動作となる:

shared_ptr<T> a = ...;
shared_ptr<T> b = ...;
if (a.get() < b.get()) {}

このような、shared_ptrが保持するポインタの比較を、「値ベース(value-based)な比較」と言う。

この比較に依存してshared_ptrstd::setstd::mapの要素型とすると、問題が起こることがある。shared_ptrには、別名コンストラクタ(aliasing constructor)と呼ばれる、以下のオーバーロードがある:

template<class Y>
shared_ptr(const shared_ptr<Y>& r, T* p) noexcept;

このコンストラクタを使用すると、所有するリソースはrだが、保持するポインタはpという状況が発生する。そのため、std::set<std::shared_ptr<T>>を使用する場合に、同じリソースが重複登録されることがある。

owner_before()は、たとえ別名コンストラクタが使われたとしても、所有するリソースのポインタ比較を行う。この比較方法を、「所有権ベース(ownership-based)な比較」と言う。

技術的には、shared_ptrが内部でメモリ確保している、参照カウンタオブジェクトのポインタ比較を行う。

#include <iostream>
#include <memory>

struct X {
  int i;
  int j;
};

int main()
{
  std::shared_ptr<X> org(new X());

  std::shared_ptr<int> a(org, &(org->i));
  std::shared_ptr<int> b(org, &(org->j));

  bool value_based_result = a < b;
  bool ownership_based_result = a.owner_before(b); // a and b are equivalent

  std::cout << std::boolalpha;
  std::cout << value_based_result << std::endl;
  std::cout << ownership_based_result << std::endl;
}

出力

true
false

バージョン

言語

  • C++11

処理系

関連項目

参照