Unretained是对internal::UnretainedWrapper进行的封装。
static inline internal::UnretainedWrapper<T> Unretained(T* o) { return internal::UnretainedWrapper<T>(o); }
而UnretainedWrapper其实很简单,就只实现了一个get()操作,把传入的指针存在类里面而已:
template <typename T> class UnretainedWrapper { public: explicit UnretainedWrapper(T* o) : ptr_(o) {} T* get() const { return ptr_; } private: T* ptr_; };
--------------------------------------------------------------------------------------------------------------------------------
RetainedRef则相对复杂一些,它是internal::RetainedRefWrapper的封装。
template <typename T> static inline internal::RetainedRefWrapper<T> RetainedRef(T* o) { return internal::RetainedRefWrapper<T>(o); } template <typename T> static inline internal::RetainedRefWrapper<T> RetainedRef(scoped_refptr<T> o) { return internal::RetainedRefWrapper<T>(std::move(o)); }
观察RetainedRefWrapper的定义,可以发现它用scoped_refptr(http://chromium.world/?id=8)把指针包裹起来。在RetainedRefWrapper构造的时候,scoped_refptr也会被构造,从而给ptr加上1次引用计数。同理,在销毁时,ptr的引用计数也会减少1。
template <typename T> class RetainedRefWrapper { public: explicit RetainedRefWrapper(T* o) : ptr_(o) {} explicit RetainedRefWrapper(scoped_refptr<T> o) : ptr_(std::move(o)) {} T* get() const { return ptr_.get(); } private: scoped_refptr<T> ptr_; };
--------------------------------------------------------------------------------------------------------------------------------
再来是Owned。它是OwnedWrapper的封装。
template <typename T> static inline internal::OwnedWrapper<T> Owned(T* o) { return internal::OwnedWrapper<T>(o); } template <typename T> static inline internal::OwnedWrapper<T> Owned(std::unique_ptr<T>&& ptr) { return internal::OwnedWrapper<T>(std::move(ptr)); }
不难理解,它是对于unique_ptr的二次封装,在构造时,将指针转移给unique_ptr<T> ptr,后续则由unique_ptr管理,从而实现“占有”的语义。
template <typename T> class OwnedWrapper { public: explicit OwnedWrapper(T* o) : ptr_(o) {} explicit OwnedWrapper(std::unique_ptr<T>&& ptr) : ptr_(std::move(ptr)) {} T* get() const { return ptr_.get(); } private: std::unique_ptr<T> ptr_; };
本文由@leonwxqian (各社交媒体同号)编写。
Passed,与前面类似,是PassedWrapper的封装。
template <typename T, std::enable_if_t<!std::is_lvalue_reference<T>::value>* = nullptr> static inline internal::PassedWrapper<T> Passed(T&& scoper) { return internal::PassedWrapper<T>(std::move(scoper)); } template <typename T> static inline internal::PassedWrapper<T> Passed(T* scoper) { return internal::PassedWrapper<T>(std::move(*scoper)); }
它的实现稍微复杂一些,Passed是一个用于忽略const的scoper的、可以复制的适配器。它实现了Take()语义,猜测是用于unique_ptr之类的指针管理类,Take以后的内容在它的scoper_中存活。
template <typename T> class PassedWrapper { public: explicit PassedWrapper(T&& scoper) : is_valid_(true), scoper_(std::move(scoper)) {} PassedWrapper(PassedWrapper&& other) : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {} T Take() const { CHECK(is_valid_); is_valid_ = false; return std::move(scoper_); } private: mutable bool is_valid_; mutable T scoper_; };
--------------------------------------------------------------------------------------------------------------------------------
IgnoreResult,是IgnoreResultHelper的封装。
template <typename T> static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { return internal::IgnoreResultHelper<T>(std::move(data)); }
可以看到它只是简单地保存了仿函数functor_。
template <typename T> struct IgnoreResultHelper { explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {} explicit operator bool() const { return !!functor_; } T functor_; };
再下面一些还定义了这个仿函数的语义,即通过这个类构造一个可以忽略返回结果的仿函数并提供执行(Invoke)语义。
// For IgnoreResults. template <typename T> struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> { using RunType = typename ForceVoidReturn<typename FunctorTraits<T>::RunType>::RunType; template <typename IgnoreResultType, typename... RunArgs> static void Invoke(IgnoreResultType&& ignore_result_helper, RunArgs&&... args) { FunctorTraits<T>::Invoke( std::forward<IgnoreResultType>(ignore_result_helper).functor_, std::forward<RunArgs>(args)...); } };