我对以下代码有疑问(这是一个非常简化的示例,可在我的程序中重现错误):
#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;
}
错误如下:
error: cannot convert 'const CDerived<double>' to 'int' in initialization
如何解决? (优先修改基类而不是派生类,如果可能不使用虚拟)
非常感谢
编辑:
如果我将相关行替换为:CDerived<int> di(CBase<int>(CBase<double>(dd1)));
它有效,但不是很实用...
编辑:似乎可以这样解决:
template <class T2> CDerived(const CDerived<T2> &x) : CBase<T>(static_cast<const CBase<T2>&>(x)) {;}
最佳答案
CDerived<int> di(dd1); // <- The problem is here
这会调用 CDerived
的第一个构造函数,等等 T2
被推断为 CDerived<double>
这是 dd1
的类型.然后,dd1
变成 x
在构造函数中; x
这是 CDerived<double>
, 被传递给接受 int
的基类构造函数(这是类型参数 T
到 CDerived
类模板的值)。因此错误,如CDerived<double>
无法转换为 int
.注意 T
的 CBase
是int
.
将其视为:
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
如果你想让你的代码工作,那么这样做:
- 首先公开而不是私下。
- 添加另一个采用
CDerived<T2>
的构造函数作为参数。
所以你需要这样做:
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() {;}
};
它现在应该可以工作了:online demo
关于c++ - 模板类继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10758686/