我有以下代码:
#include <iostream>
#include "boost/shared_ptr.hpp"
using boost::shared_ptr;
class Base {
public:
virtual ~Base() {}
virtual void print() = 0;
};
template <typename T>
class Child : public Base {
public:
virtual void print() {
std::cout << "in Child" << std::endl;
}
};
class GrandChild : public Child<int> {
public:
virtual void print() {
std::cout << "in GrandChild" << std::endl;
}
};
template <typename T>
void call_print(shared_ptr<Child<T> > a) {
a->print();
}
void call_base_print(shared_ptr<Base> a) {
a->print();
}
int main() {
shared_ptr<GrandChild> gchild(new GrandChild);
call_print(shared_ptr<Child<int> >(gchild));
// call_print(gchild); // Cannot compile!
call_base_print(gchild); // This works.
return 0;
}
我发现call_base_print(gchild)
有效但call_print(gchild)
会导致编译错误,这很奇怪。我知道C ++不允许两次隐式转换,但我不认为这里有两次转换......有人可以启发我吗?
答案 0 :(得分:5)
你没有达到类型转换的程度。它在模板实例化中更早失败。
call_base_print
不需要类型扣除。 call_print<T>(shared_ptr<Child<T> > a)
。你传递的是shared_ptr<GrandChild>
。并且根本没有T可以代替,shared_ptr<Child<T> >
是shared_ptr<GrandChild>
。因此,实例化失败,并且没有调用函数。
答案 1 :(得分:0)
您希望shared_ptr<GrandChild>
派生自shared_ptr<Child>
,然后才能进行隐式转换。它不是;这是一个不同的类型。所以call_print
期待的是另一种类型的参数而不是你提供的。
另一个警告:即使从子类转换到超类,也会导致子类对象的切片,因为你按值提供参数。
您可以使用指针参数i.s.o来获取您的目标行为。 shared_ptr
秒。