前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++模版笔记(2)

C++模版笔记(2)

作者头像
一只小虾米
发布2022-10-25 16:52:25
4890
发布2022-10-25 16:52:25
举报
文章被收录于专栏:Android点滴分享

本篇介绍

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

std::enable_if<>

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

代码语言:javascript
复制
template< bool B, class T = void >
using enable_if_t = typename enable_if<B,T>::type;

查看下面的例子:

代码语言:javascript
复制
 template<typename T>
   std::enable_if_t<(sizeof(T) > 4)>
   foo() {
   }

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

代码语言:javascript
复制
template<typename T,
            typename = std::enable_if_t<(sizeof(T) > 4)>>
void foo() { }

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

代码语言:javascript
复制
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,这样就可以在编译态作为开关,如下所示:

代码语言:javascript
复制
  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, 原因是什么呢? 看下源码

代码语言:javascript
复制
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。看下他的实现:

代码语言:javascript
复制
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前,该对象已经被智能指针持有了。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本篇介绍
    • std::enable_if<>
      • 编译时的if
        • enable_shared_from_this
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档