美文网首页
C++模版笔记(2)

C++模版笔记(2)

作者: android小奉先 | 来源:发表于2022-09-04 18:48 被阅读0次

    本篇介绍

    本篇继续C++的模版介绍

    std::enable_if<>

    enable_if<> 的作用是满足条件后可以使用模版推导,基于SFINAE(substitution failure is not an error), 这样可以按照条件控制是否使用模版。

    template< bool B, class T = void >
    using enable_if_t = typename enable_if<B,T>::type;
    

    查看下面的例子:

     template<typename T>
       std::enable_if_t<(sizeof(T) > 4)>
       foo() {
       }
    

    就是在 T的大小超过4之后,就推导出void fun() {}
    有时候也可以这样写:

    template<typename T,
                typename = std::enable_if_t<(sizeof(T) > 4)>>
    void foo() { }
    

    在C++20中,也可以不使用enable_if, 通过requires 和concept关键字即可:

    template<typename STR>
       requires std::is_convertible_v<STR,std::string>
       Person(STR&& n) : name(std::forward<STR>(n)) {
    }
    
    template<typename T>
       concept ConvertibleToString = std::is_convertible_v<T,std::string>;
    
    

    编译时的if

    c++17支持编译时的if,这样就可以在编译态作为开关,如下所示:

      template<typename T, typename... Types>
       void print (T const& firstArg, Types const&... args)
       {
         std::cout << firstArg << ’\n’;
         if constexpr(sizeof...(args) > 0) {
         print(args...); // code only available if sizeof...(args)>0 (since C++17) }
       }
    

    enable_shared_from_this

    遇到需要用this 构造shared_ptr的时候都需要继承一下 enable_shared_from_this, 原因是什么呢? 看下源码

    template<class _Tp>
    class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
    {
        mutable weak_ptr<_Tp> __weak_this_;
    protected:
        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
        enable_shared_from_this() _NOEXCEPT {}
        _LIBCPP_INLINE_VISIBILITY
        enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
        _LIBCPP_INLINE_VISIBILITY
        enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
            {return *this;}
        _LIBCPP_INLINE_VISIBILITY
        ~enable_shared_from_this() {}
    public:
        _LIBCPP_INLINE_VISIBILITY
        shared_ptr<_Tp> shared_from_this()
            {return shared_ptr<_Tp>(__weak_this_);}
        _LIBCPP_INLINE_VISIBILITY
        shared_ptr<_Tp const> shared_from_this() const
            {return shared_ptr<const _Tp>(__weak_this_);}
    
    #if _LIBCPP_STD_VER > 14
        _LIBCPP_INLINE_VISIBILITY
        weak_ptr<_Tp> weak_from_this() _NOEXCEPT
           { return __weak_this_; }
    
        _LIBCPP_INLINE_VISIBILITY
        weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
            { return __weak_this_; }
    #endif // _LIBCPP_STD_VER > 14
    
        template <class _Up> friend class shared_ptr;
    };
    

    这里面有一个_weak_this, 可是没有赋值的地方,那是哪儿赋值的呢?看到有一个friend shared_ptr。看下他的实现:

    shared_ptr<_Tp>::shared_ptr(_Yp* __p,
                                typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
        : __ptr_(__p)
    {
        unique_ptr<_Yp> __hold(__p);
        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
        typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, _AllocT > _CntrlBlk;
        __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), _AllocT());
        __hold.release();
        __enable_weak_this(__p, __p);
    }
    
            __enable_weak_this(const enable_shared_from_this<_Yp>* __e,
                               _OrigPtr* __ptr) _NOEXCEPT
            {
                typedef typename remove_cv<_Yp>::type _RawYp;
                if (__e && __e->__weak_this_.expired())
                {
                    __e->__weak_this_ = shared_ptr<_RawYp>(*this,
                        const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
                }
            }
    

    看到这儿就可以得出以下结论:

    1. shared_from_this本质上是通过一个弱指针来感知this是否有效,并且利用弱指针来创建shared_ptr
    2. 弱指针是在首次使用智能指针创建对应对象的时候初始化的,那么就需要要求调用shared_from_this前,该对象已经被智能指针持有了。

    相关文章

      网友评论

          本文标题:C++模版笔记(2)

          本文链接:https://www.haomeiwen.com/subject/hptmnrtx.html