具有模板和构造函数的两个派生类的多重继承

时间:2016-07-25 15:54:54

标签: c++ c++14

我跟随here的示例,但是我使用模板并调用其中一个派生类的构造函数。以下代码在没有模板的情况下工作,但在包含时我不确定为什么会出现以下错误:

: error: no matching function for call to ‘AbsInit<double>::AbsInit()’
     NotAbsTotal(int x) : AbsInit(x) {};
                                   ^

以下是代码:

#include <iostream>

using namespace std;

template<typename T>
class AbsBase
{
    virtual void init() = 0;
    virtual void work() = 0;
};

template<typename T>
class AbsInit : public virtual AbsBase<T>
{
public:
    int n;
    AbsInit(int x)
    {
        n = x;
    }
    void init() {  }
};

template<typename T>
class AbsWork : public virtual AbsBase<T>
{
    void work() {  }
};

template<typename T>
class NotAbsTotal : public AbsInit<T>, public AbsWork<T>
{
public:
    T y;
    NotAbsTotal(int x) : AbsInit(x) {};
};    // Nothing, both should be defined


int main() {
  NotAbsTotal<double> foo(10);
  cout << foo.n << endl;

}

2 个答案:

答案 0 :(得分:2)

您需要将 template-argument (在本例中为T)传递给基本模板类

更改此

template<typename T>
class NotAbsTotal : public AbsInit<T>, public AbsWork<T>
{
public:
    T y;
    NotAbsTotal(int x) : AbsInit<T>(x) // You need to pass the template parameter
    {};
};    

答案 1 :(得分:2)

在下面的摘录中......

template<typename T>
class NotAbsTotal : public AbsInit<T>
{
    NotAbsTotal(int x) : AbsInit(x) {}
};

... AbsInit<T>dependent base class

  

依赖基类是一个基类,它是一个依赖类型,不是当前的实例化。

...尝试使用不合格的injected-class-nameAbsInit)来引用,但是:

  

为了名称隐藏和查找的目的,类的注入类名(子句[class])也被认为是该类的成员。

...但是,[temp.dep]/p3

  

在类或类模板的定义中,在非限定名称查找期间不检查从属基类的范围[temp.dep.type] 类模板或成员的定义点,或者在类模板或成员的实例化过程中。 [示例

typedef double A;
template<class T> class B {
  typedef int A;
};
template<class T> struct X : B<T> {
  A a;              // a has type double
};
     

[...]

     

- 结束示例]

因此,AbsInit不能绑定到{em>注入类名,它存在于AbsInit<T>本身的范围内。该名称单独留下unqualified name lookup,并且指的是在全局命名空间中找到的类模板。

要避免错误或强制执行所需的名称解析,请将模板参数列表附加到类模板名称AbsInit

NotAbsTotal(int x) : AbsInit<T>(x) {}
//                          ~~^

或使用限定名称:

NotAbsTotal(int x) : NotAbsTotal::AbsInit(x) {}
//                   ~~~~~~~~~~^

备注:一旦基类不依赖(即使用具体类型,例如AbsInit<int>),就可以使用注入类名称的非限定形式。