std::shared_ptr 在通过引用传递时如何跨类层次结构进行转换

How does std::shared_ptr converts across class hierarchy when passing by reference?

本文关键字:何跨类 层次结构 转换 引用 ptr shared std      更新时间:2023-10-16

查看 20.8.2.2 类模板shared_ptr [util.smartptr.shared] 我意识到std::shared_ptr具有模板复制构造函数和赋值运算符,当且仅当Derived*可转换为Base*时,才允许从shared_ptr<Derived>转换为shared_ptr<Base>。这些转换(在我的理解中)仅通过模板化复制构造函数和赋值运算符完成。但是,似乎我也可以将shared_ptr<Derived>传递给需要shared_ptr<Base>&的函数(即通过引用传递)。似乎应该有一个隐式转换运算符,但根据标准没有。

下面的代码阐明了我的意思:

#include <iostream>
#include <memory>
struct Base {};
struct Derived: Base {};
void f(const std::shared_ptr<Base>& ) {}
int main()
{
    std::shared_ptr<Derived> spDerived(new Derived);
    // conversion below is OK, via template copy ctor
    std::shared_ptr<Base> spBase(spDerived); 
    // also OK, via template copy assignment operator
    spBase = spDerived; 
    // why is this OK? Cannot see any conversion operators in
    // 20.8.2.2 Class template shared_ptr [util.smartptr.shared]
    f(spDerived); 
}

我的问题:在这种情况下,谁在呼叫f(spDerived)中执行从shared_ptr<Derived>shared_ptr<Base>的转换?(对于编译器shared_ptr<Derived>shared_ptr<Base>没有任何关系,即使DerivedBase的子代)

临时是通过模板复制 ctor 创建的,该副本是引用的。CTOR 是隐式的,因此在这种情况下可以合法地调用它。从根本上说,这个电话和说f(std::string); f("hello");之间没有区别。完全相同的机制也在起作用。这是常规的隐式转换。