传递shared_ptr <derived>&amp; as shared_ptr <base />&amp;没有const </derived>

时间:2014-09-19 02:54:41

标签: c++ inheritance c++11 casting shared-ptr

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引用传递,但只是想知道编译错误发生的原因。

1 个答案:

答案 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}}不能以类似的方式工作的原因。