I believe that the standard way to atomically load and store shared pointers is to use the functions in §20.7.2.5 [util.smartptr.shared.atomic]. It seems only libC ++ clang supports them:
template<class T> bool atomic_is_lock_free(const shared_ptr<T>* p); template<class T> shared_ptr<T> atomic_load(const shared_ptr<T>* p); template<class T> shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo); template<class T> void atomic_store(shared_ptr<T>* p, shared_ptr<T> r); template<class T> void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo); template<class T> shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r); template<class T> shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo); template<class T> bool atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w); template<class T> bool atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w); template<class T> bool atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w, memory_order success, memory_order failure); template<class T> bool atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w, memory_order success, memory_order failure);
So, the code can be written as:
auto ptr = std::make_shared<MyClass>(); printf("1. use_count=%d\n", ptr.use_count()); { auto p = std::atomic_load(&ptr); printf("3a. use_count=%d\n", ptr.use_count()); } printf("3b. use_count=%d\n", ptr.use_count()); { auto p = std::atomic_load(&ptr); printf("3a. use_count=%d\n", ptr.use_count()); } printf("4b. use_count=%d\n", ptr.use_count());
But I can not find such support listed in MSDN, so it is best to use a mutex. (In fact, the implementation of these functions in libC ++ also uses the mutex.)
source share