将shared_ptr<Derived>&
作为shared_ptr<Base>&
传递时出现编译错误,请参阅以下代码和详细问题。
注意:此问题类似于“Passing shared_ptr<Derived> as shared_ptr<Base>
”,但不重复。
#include <memory>
class TBase
{
public:
virtual ~TBase() {}
};
class TDerived : public TBase
{
public:
virtual ~TDerived() {}
};
void FooRef(std::shared_ptr<TBase>& b)
{
// Do something
}
void FooConstRef(const std::shared_ptr<TBase>& b)
{
// Do something
}
void FooSharePtr(std::shared_ptr<TBase> b)
{
// Do something
}
int main()
{
std::shared_ptr<TDerived> d;
FooRef(d); // *1 Error: invalid initialization of reference of type ‘std::shared_ptr<TBase>&’ from expression of type ‘std::shared_ptr<TDerived>’
FooConstRef(d); // *2 OK, just pass by const reference
FooSharePtr(d); // *3 OK, construct a new shared_ptr<>
return 0;
}
由g++ -std=c++11 -o shared_ptr_pass_by_ref shared_ptr_pass_by_ref.cpp
环境:Ubuntu 14.04,g ++(Ubuntu 4.8.2-19ubuntu1)4.8.2
详细问题: 为什么通过const引用(* 2)传递,但不能通过引用传递(* 1)?
注意:我知道最佳做法是通过const引用传递,但只是想知道编译错误发生的原因。
答案 0 :(得分:3)
您似乎期望某种模板协方差,AnyTemplateClass<Derived>
可以绑定到AnyTemplateClass<Base>&
。模板不能以这种方式工作。通常,AnyTemplateClass<Derived>
和AnyTemplateClass<Base>
是两个截然不同的,完全不相关的类。
特定模板类可以或者当然以某种形式提供关系。 shared_ptr<T>
特别是模板化构造函数接受shared_ptr<U>
U
U*
,T*
可转换为FooConstRef(d)
。
shared_ptr<TBase> temp(d);
FooConstRef(temp);
调用通过构建临时 - 有效
FooRef(d)
但是临时工具不能绑定到非const引用,这就是为什么{{1}}不能以类似的方式工作的原因。