make_share

本章所有内容均从C++ Primer摘录总结
1.为什么使用make_shared?

    make_shared函数的主要功能是在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr;由于是通过shared_ptr管理内存,因此一种安全分配和使用动态内存的方法。

     如下为make_shared的使用:


   
   
  1. //p1指向一个值为"9999999999"的string
  2. shared_ptr< string> p1 = make_shared< string>( 10, '9');
  3. shared_ptr< string> p2 = make_shared< string>( "hello");
  4. shared_ptr< string> p3 = make_shared< string>();
从上述例子我们可以看出以下几点:
  1)make_shared是一个模板函数;
  2)make_shared模板的使用需要以“显示模板实参”的方式使用,如上题所示make_shared<string>(10, 9),如果不传递显示 模板实参string类型,make_shared无法从(10, '9')两个模板参数中推断出其创建对象类型。
  3)make_shared在传递参数格式是可变的,参数传递为生成类型的构造函数参数,因此在创建shared_ptr<T>对象的过程中调用了类型T的某一个构造函数。

2.make_shared模板实现
  如下为make_shared的库函数实现版本:


   
   
  1. template< typename _Tp, typename... _Args>
  2. inline shared_ptr<_Tp>
  3. make_shared(_Args&&... __args)
  4. {
  5. typedef typename std::remove_const<_Tp>::type _Tp_nc;
  6. return std::allocate_shared<_Tp>( std::allocator<_Tp_nc>(),
  7. std::forward<_Args>(__args)...);
  8. }
  9. template< typename _Tp, typename _Alloc, typename... _Args>
  10. inline shared_ptr<_Tp>
  11. allocate_shared( const _Alloc& __a, _Args&&... __args)
  12. {
  13. return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a,
  14. std::forward<_Args>(__args)...);
  15. }
我们依次分析上述的关键代码

   
   
  1. //关键行1
  2. template< typename _Tp, typename... _Args>
  3. inline shared_ptr<_Tp> make_shared(_Args&&... __args)
  4. //关键行2
  5. std::forward<_Args>(__args)...
  6. //关键行3
  7. return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a,
  8. std::forward<_Args>(__args)...);
从上述关键代码可以看出: make_shared是组合使用可变参数模板与forward(转发)机制实现将实参保持不变地传递给其他函数。如最开始的string例子
1) 使用可变参数:是因为string有多个构造函数,且参数各不相同;

2)Args参数为右值引用(Args&&)和std::forward:是为了保持实参中类型信息的传递。这样当传递一个右值string&& 对象给make_shared时,就可以使用string的移动构造函数进行初始化。注意,两者必须结合使 用,缺一不可;

此外std::forward<_Args>(__args)...是采用 包扩展形式调用的,原理如下:

   
   
  1. shared_ptr< string> p1 = make_shared< string>( 10, '9');
  2. //扩展如下,对两个参数分别调用std::forward
  3. return shared_ptr< string>(_Sp_make_shared_tag(), _a ,
  4. std::forward< int>( 10),
  5. std::forward< char>(c));
补充说明:
①模板参数为右值引用,采用引用折叠原理:

   
   
  1. 1)参数为左值时,实参类型为普通的左值引用; T& &, T&& &,T& && =>T&
  2. 2)参数为右值时,实参类型为右值: T&& && => T&&
std::forward:是一个模板,通过显示模板实参来调用,调用后forward返回显示实参类型的右值引用。即,forward<T>的返回类型为T&&,在根据上述引用折叠原理即可保存参数是左值还是右值类型;比如:

   
   
  1. int i = 0;
  2. std::forward< int>(i), i将以 int&传递
  3. std::forward< int>( 42), 42将以 int&&传递
std::forward实现代码:

   
   
  1. /**
  2. * @brief Forward an lvalue.
  3. * @return The parameter cast to the specified type.
  4. *
  5. * This function is used to implement "perfect forwarding".
  6. */
  7. template< typename _Tp>
  8. constexpr _ Tp&&
  9. forward (typename std::remove_reference<_Tp>::type& __t) noexcept
  10. { return static_cast<_Tp&&>( __t); }
  11. /**
  12. * @brief Forward an rvalue.
  13. * @return The parameter cast to the specified type.
  14. *
  15. * This function is used to implement "perfect forwarding".
  16. */
  17. template< typename _Tp>
  18. constexpr _ Tp&&
  19. forward (typename std::remove_reference<_Tp>::type&& __t) noexcept
  20. {
  21. static_assert(! std::is_lvalue_reference<_Tp>::value, "template argument"
  22. " substituting _Tp is an lvalue reference type");
  23. return static_cast<_Tp&&>( __t);
  24. }






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用pcl1.8代码的CMakeLists.txt中,您可以添加以下内容来指定PCL的安装路径:set(PCL_DIR "/usr/local/pcl18/share/pcl-1.8")。这将帮助CMake在构建过程中找到正确的PCL库文件。 在安装pcl1.8时,可能会遇到各种问题。在Ubuntu16.04系统下安装pcl1.8时,可能会出现缺少libpclcommon.so的错误。为了解决这个问题,您可以按照以下步骤进行操作: 1. 首先,确保您已经安装了PCL库。您可以按照网上的教程进行安装,建议使用pcl1.8版本,因为它被认为是比较稳定和好用的版本。这将帮助您在需要兼容pcl1.10时找到正确的PCL库文件。 关于您提到的make_shared函数的问题,可以提供更多上下文信息吗?make_shared函数是C++中的一个模板函数,用于创建共享指针,它不直接与PCL相关。如果您有关于make_shared函数的具体问题,请提供更多详细信息,我将尽力为您解答。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Ubuntu20.04 编译 pcl1.8可能出现的问题](https://blog.csdn.net/dui845819593/article/details/128486864)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [ubuntu20安装pcl1.8](https://blog.csdn.net/MintLab/article/details/128722334)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值