- memory[meta header]
- std[meta namespace]
- shared_ptr[meta class]
- function template[meta id-type]
- cpp11[meta cpp]
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
- weak_ptr[link /reference/memory/weak_ptr.md]
所有権ベースでの小なり比較を行う。
*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_ptr
をstd::set
やstd::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;
}
- owner_before[color ff0000]
true
false
- C++11
- GCC: 4.4.7 [mark verified]
- Clang: 3.0 [mark verified]
- ICC: ?
- Visual C++: 2010 [mark verified], 2012 [mark verified], 2013 [mark verified]