C++中std::remove_pointer的具体作用及相关代码行解析
代码逐段解读
你对std::remove_pointer的猜想是完全正确的,这行代码是典型的泛型场景下自动推导类型的写法,我们从内到外拆解每一部分的作用:
- 首先看最内层的
myPublisher.get():支持.get()方法返回裸指针,说明myPublisher本身是std::shared_ptr类型的智能指针——毕竟只有shared_ptr可以直接构造std::weak_ptr。 decltype(myPublisher.get()):decltype会拿到传入表达式的静态编译期类型,std::shared_ptr<T>::get()的返回值固定为T*(指向托管对象的裸指针),所以这一步拿到的类型是「指向myPublisher托管对象的裸指针类型」。举个例子,如果myPublisher是std::shared_ptr<RosPublisher>,这一步得到的类型就是RosPublisher*。std::remove_pointer<上一步得到的指针类型>::type:这是C++标准库提供的类型萃取工具,作用就是剥离类型外层的指针修饰:传入U*类型时,它的内部type成员就对应U类型;如果传入的不是指针类型,type就是传入类型本身。放在这里的作用,就是把上一步拿到的T*裸指针类型的指针属性去掉,得到原始的托管对象类型T。- 最外层
std::weak_ptr<萃取出的T类型> captured_pub = myPublisher;:这部分就是定义了一个指向T类型对象的弱智能指针,用myPublisher初始化。弱指针不会增加托管对象的引用计数,一般用来避免循环引用、或者在异步回调里安全判断对象是否已经被销毁,避免悬空指针问题。
为什么要写得这么绕?
如果是固定类型的业务代码,这行完全可以直接写成对应类型的弱指针,比如前面举例的场景直接写std::weak_ptr<RosPublisher> captured_pub = myPublisher;即可,不需要做类型萃取。
这种嵌套萃取的写法基本只出现在泛型模板代码里:当
myPublisher的类型是模板参数,不固定指向哪种发布者实现时,这种写法可以自动适配任意类型的shared_ptr,不需要硬编码托管对象的类型,减少模板实例化时的类型不匹配问题。
这里有个容易踩的误区:std::remove_pointer在这里没有什么特殊的功能逻辑,纯粹是因为shared_ptr::get()返回的是带指针修饰的T*,如果不把指针层剥掉,直接把decltype(myPublisher.get())传给weak_ptr,就会得到std::weak_ptr<T*>——这是非法的写法,weak_ptr的类型参数必须是对象类型,不能是指针类型。
举个完整的类型推导例子:
// 假设myPublisher的定义如下 std::shared_ptr<MessagePublisher> myPublisher = std::make_shared<MessagePublisher>(); // 逐段推导你遇到的那行代码: // 1. myPublisher.get() 返回 MessagePublisher* // 2. decltype(myPublisher.get()) 得到编译期类型 MessagePublisher* // 3. std::remove_pointer<MessagePublisher*>::type 得到 MessagePublisher // 4. 最终整行代码等价于: std::weak_ptr<MessagePublisher> captured_pub = myPublisher;
内容的提问来源于stack exchange,提问作者Yaniv G
相关产品推荐
相关产品推荐

