• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

    最終更新日時(UTC):
    が更新

    履歴 編集

    function template
    <memory>

    std::shared_ptr::owner_before

    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

    処理系

    関連項目

    参照