看着20.8.2.2类模板的shared_ptr [util.smartptr.shared]我意识到std::shared_ptr
具有模板拷贝构造函数和赋值运算符,允许从shared_ptr<Derived>
到shared_ptr<Base>
转换当且仅当Derived*
可转换为Base*
。只有通过模板拷贝构造函数和赋值操作符才能完成这些转换(以我的理解)。不过,我似乎也可以将shared_ptr<Derived>
传递给需要shared_ptr<Base>&
(即通过引用传递)的函数。似乎应该有一个隐式转换运算符,但根据标准,没有。当通过引用传递时,std :: shared_ptr如何通过类层次转换?
下面的代码阐明了我的意思:
#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);
}
我的问题:在这种情况下,谁是执行从shared_ptr<Derived>
转换为shared_ptr<Base>
呼叫f(spDerived)
? (为shared_ptr<Derived>
与shared_ptr<Base>
没有任何关系,即使Derived
是Base
子编译)
通过转换构造函数创建临时'std :: shared_ptr ',并绑定到引用。换句话说,调用等价于'f(std :: shared_ptr (spDerived))' –
我说转换构造函数,而不是复制构造函数(构造函数模板从不复制构造函数; /结束迂腐模式)。无论如何,你怎么知道没有构造函数被调用?由于你的功能是无操作的,很可能整个呼叫都被优化掉了。 –
@IgorTandetnik我想我明白发生了什么,编译器可以执行一个用户定义的转换,并且可以调用模板转换ctor ... temp然后绑定到const ref。 – vsoftco