c++ - 模板类继承

标签 c++ templates inheritance

我对以下代码有疑问(这是一个非常简化的示例,可在我的程序中重现错误):

#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 的基类构造函数(这是类型参数 TCDerived 类模板的值)。因此错误,如CDerived<double>无法转换为 int .注意 TCBaseint .

将其视为:

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

如果你想让你的代码工作,那么这样做:

  1. 首先公开而不是私下
  2. 添加另一个采用 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/

相关文章:

C++ 概念检查与继承

go - 工厂模式下的结构继承

c++ - 为什么我的 mp4 文件只有 414 字节? (Xcode)(C++)

iphone - 如何使用 Xcode4 项目模板将文件添加到复制捆绑资源构建阶段

c++ - 在 C++ 中从内部循环中跳出外部循环

templates - Visual Studio 2017 ASP NET Core 2 脚手架模板

c# - 我怎样才能记住 super 调用父级?

c# - .NET C# 在父接口(interface)中显式实现祖 parent 的接口(interface)方法

c++ - 可以使用 static_cast 破坏 protected 成员访问检查吗?

C++函数计算字符串中的所有单词