Template class inheritance
c++, inheritance, templates
Solution
CDerived<int> di(dd1); // <- The problem is here
This invokes the first constructor of `CDerived`, and so `T2` is inferred as `CDerived<double>` which is the type of `dd1`. Then, `dd1` becomes `x` in the constructor; `x` which is `CDerived<double>`, gets passed to the base class constructor which accepts `int` (which is the value of the type argument `T` to `CDerived` class template). Hence the error, as `CDerived<double>` cannot be converted into `int`. Note that `T` of `CBase` is `int`.
See it as:
CDerived<int> di(dd1); // <- The problem is here
^ ^
| |
| this helps compiler to deduce T2 as double
|
this is T of the CDerived as well as of CBase
If you want to make your code work, then do this:
- First derive publicly instead of privately.
- Add another constructor taking `CDerived<T2>` as parameter.
So you need to so this:
template<class T> class CDerived : public CBase<T> //derived publicly
{
public:
template <class T2> CDerived(const T2 &x) : CBase<T>(x) {;}
//add this constructor
template <class T2> CDerived(const CDerived<T2> &x) : CBase<T>(x.var()) {;}
template <class T2> CDerived (const CBase<T2> &x) : CBase<T>(x) {;}
~CDerived() {;}
};
It should work now : online demo
Problem
I have a problem with the following piece of code (it is a very simplified example that reproduce the error in my program) : ``` #include <iostream> using namespace std; template<class T> class CBase { public: template <class T2> CBase(const T2 &x) : _var(x) {;} template <class T2> CBase (const CBase<T2> &x) {_var = x.var();} ~CBase() {;} T var() const {return _var;} protected: T _var; }; template<class T> class CDerived : public CBase<T> { public: template <class T2> CDerived(const T2 &x) : CBase<T>(x) {;} template <class T2> CDerived (const CBase<T2> &x) : CBase<T>(x) {;} ~CDerived() {;} }; int main() { CBase<double> bd(3); CBase<int> bi(bd); // <- No problem CDerived<double> dd1(3); CDerived<double> dd2(dd1); CDerived<int> di(dd1); // <- The problem is here return 0; } ``` And the error is the following : ``` error: cannot convert 'const CDerived<double>' to 'int' in initialization ``` How to solve that ? (with a preference for modifications in the base class and not in the derived class, and if possible no use of virtuality) Thank you very much EDIT : If I replace the concerned line with : `CDerived<int> di(CBase<int>(CBase<double>(dd1)));` it works but it is not very practical... EDIT : Seems to be solved by that : ``` template <class T2> CDerived(const CDerived<T2> &x) : CBase<T>(static_cast<const CBase<T2>&>(x)) {;} ```