C ++ Templates and Implicit Type Conversion

I have the following code:

#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; } 

It was strange to me that call_base_print(gchild) works, but call_print(gchild) causes a compiler error. I know that C ++ does not allow two implicit conversions, but I don't think there are two conversions here ... Can someone enlighten me?

+4
source share
2 answers

You cannot go to type conversion. It does not work before when creating a template.

call_base_print does not require type inference. call_print<T>(shared_ptr<Child<T> > a) does. You pass shared_ptr<GrandChild> . And there simply isn’t T, you can replace it so that shared_ptr<Child<T> > is shared_ptr<GrandChild> . Therefore, instance creation fails, and there is no function to call.

+5
source

You expect shared_ptr<GrandChild> obtained from shared_ptr<Child> , only then can an implicit conversion be performed. This is not true; this is a different type. So call_print expects a different type of argument that you provide.

Another warning: even if there was a transition from a subclass to a superclass, this will lead to cutting the object of the subclass, because you provide arguments by value.

You can get the behavior you are aiming for by using the iso shared_ptr c pointer arguments.

0
source

All Articles