yohhoyの日記

技術的メモをしていきたい日記

空のweak_ptrと期限切れを判別

C++11標準ライブラリまたはBoost.Smart_Pointersライブラリが提供するスマートポインタweak_ptrにて、空(empty)状態と参照先の期限切れを区別する方法。本記事の内容はStack Overflowで見つけた質問と回答に基づく。

// C++11
#include <memory>
using namespace std;
// Boost.Smart_Pointers
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/make_shared.hpp>
using namespace boost;

template <typename T>
bool empty_weak_ptr(const weak_ptr<T>& w) {
  return !w.owner_before(weak_ptr<T>{})
      && !weak_ptr<T>{}.owner_before(w);
}

shared_ptr<int> sp1 = make_shared<int>();
weak_ptr<int> valid_wp(sp1);
// 期限切れweak_ptr
shared_ptr<int> sp2 = make_shared<int>();
weak_ptr<int> expired_wp(sp2);
sp2 = nullptr;
// 空のweak_ptr
weak_ptr<int> empty_wp;

assert( !valid_wp.expired() );
assert(  expired_wp.expired() );
assert(  empty_wp.expired() );

assert( !empty_weak_ptr(valid_wp) );
assert( !empty_weak_ptr(expired_wp) );
assert(  empty_weak_ptr(empty_wp) );

C++11(N3337) 20.7.2.3.5/p1, 3, 6より引用。

long use_count() const noexcept;
1 Returns: 0 if *this is empty; otherwise, the number of shared_ptr instances that share ownership with *this.

bool expired() const noexcept;
3 Returns: use_count() == 0.

template<class U> bool owner_before(shared_ptr<U> const& b);
template<class U> bool owner_before(weak_ptr<U> const& b);
6 Returns: An unspecified value such that

  • x.owner_before(y) defines a strict weak ordering as defined in 25.4;
  • under the equivalence relation defined by owner_before, !a.owner_before(b) && !b.owner_before(a), two shared_ptr or weak_ptr instances are equivalent if and only if they share ownership or are both empty.

関連URL