我跟随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;
}
答案 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-name(AbsInit
)来引用,但是:
为了名称隐藏和查找的目的,类的注入类名(子句[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>
),就可以使用注入类名称的非限定形式。