繁体   English   中英

C ++模板和隐式类型转换

[英]C++ templates and implicit type conversion

我有以下代码:

#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 ++不允许两次隐式转换,但我不认为这里有两次转换......任何人都可以启发我吗?

你没有达到类型转换的程度。 它在模板实例化中更早失败。

call_base_print不需要类型扣除。 call_print<T>(shared_ptr<Child<T> > a)确实如此。 您正在传递shared_ptr<GrandChild> 并且根本没有T可以替代,因为shared_ptr<Child<T> >shared_ptr<GrandChild> 因此,实例化失败,并且没有调用函数。

您希望shared_ptr<GrandChild>派生自shared_ptr<Child> ,只有这样才能进行隐式转换。 它不是; 这是一个不同的类型。 所以call_print期望的另一种类型的参数比你提供的要多。

另一个警告:即使存在从子类到超类的转换,也会导致子类对象的切片,因为您按值提供参数。

您可以使用指针参数iso shared_ptr来获取您的目标行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM