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)) {;}
This invokes the first constructor of
CDerived, and soT2is inferred asCDerived<double>which is the type ofdd1. Then,dd1becomesxin the constructor;xwhich isCDerived<double>, gets passed to the base class constructor which acceptsint(which is the value of the type argumentTtoCDerivedclass template). Hence the error, asCDerived<double>cannot be converted intoint. Note thatTofCBaseisint.See it as:
If you want to make your code work, then do this:
CDerived<T2>as parameter.So you need to so this:
It should work now : online demo