std::shared_ptr 在按引用传递时如何跨 class 层次结构进行转换?
How does std::shared_ptr converts across class hierarchy when passing by reference?
看着 20.8.2.2 Class 模板 shared_ptr [util.smartptr.shared] 我意识到std::shared_ptr
具有模板复制构造函数和赋值运算符,当且仅当 Derived*
可转换为 Base*
时才允许从 shared_ptr<Derived>
转换为 shared_ptr<Base>
。这些转换(以我的理解)仅通过模板化的复制构造函数和赋值运算符完成。但是,我似乎也可以将 shared_ptr<Derived>
传递给采用 shared_ptr<Base>&
的函数(即,通过引用传递)。好像应该有隐式转换运算符,但是按照标准有none。
下面的代码阐明了我的意思:
#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>
没有任何关系,即使 Derived
是 Base
的子代)
通过模板复制构造函数创建了一个临时文件,该副本就是所引用的。 ctor 是隐式的,因此在这种情况下可以合法地调用它。从根本上说,此调用与 f(std::string); f("hello");
之间没有区别。完全相同的机制在起作用。这是一个常规的隐式转换。
看着 20.8.2.2 Class 模板 shared_ptr [util.smartptr.shared] 我意识到std::shared_ptr
具有模板复制构造函数和赋值运算符,当且仅当 Derived*
可转换为 Base*
时才允许从 shared_ptr<Derived>
转换为 shared_ptr<Base>
。这些转换(以我的理解)仅通过模板化的复制构造函数和赋值运算符完成。但是,我似乎也可以将 shared_ptr<Derived>
传递给采用 shared_ptr<Base>&
的函数(即,通过引用传递)。好像应该有隐式转换运算符,但是按照标准有none。
下面的代码阐明了我的意思:
#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>
没有任何关系,即使 Derived
是 Base
的子代)
通过模板复制构造函数创建了一个临时文件,该副本就是所引用的。 ctor 是隐式的,因此在这种情况下可以合法地调用它。从根本上说,此调用与 f(std::string); f("hello");
之间没有区别。完全相同的机制在起作用。这是一个常规的隐式转换。