我可以在类中使用typedef函数指针:
template<typename T>
class MyClass
{
public:
typedef T (*fptr)(T);
void doSomething(fptr my_fptr) { /*...*/ }
};
这很好用。但如果我从这样的类继承,如下所示:
template<typename T>
class MyClass
{
public:
typedef T (*fptr)(T);
virtual void doSomething(fptr my_fptr) = 0;
};
template<typename T>
class MyOtherClass: public MyClass<T>
{
public:
void doSomething(fptr my_fptr) { /*...*/ }
};
编译器抱怨fptr未定义。有没有像这样继承函数指针typedef的方法?谢谢, 詹姆斯
答案 0 :(得分:4)
问题不在于继承,而在于模板从另一个模板的实例化继承,并将其自己的模板参数作为参数传递。也就是说,它继承自依赖类型(MyClass<T>
依赖于类型T
)。
该语言要求在执行类型替换之前验证模板,并且在第一次传递期间,验证所有非依赖名称。当编译器看到fptr
时,它不依赖于类型T
,因此它会尝试将其作为命名空间级别符号在模板外部找到并失败。不允许使用类型实例化MyBase
(没有替换类型),因此整个MyBase
是未知的,并且不能在那里查找符号(不替换类型,编译器无法知道是否存在MyBase
)的特定特化。
最简单的解决方案是添加本地typedef:
typedef MyBase<T> base_type;
typedef typename base_type::fptr fptr;
或完全符合通话资格:
void doSomething( typename MyClass<T>::fptr ) ...
答案 1 :(得分:1)
你应该能够继承这样的公共typedef。
你是否尝试过类似的东西来确保编译器知道它是父类型:
void doSomething(typename MyClass<T>::fptr my_fptr) { /*...*/ }
答案 2 :(得分:0)
我认为由于模板化,编译器需要更多信息:
试
typename MyClass<T>::fptr
答案 3 :(得分:0)
问题是该定义位于依赖于模板参数的基类中(称为依赖基类);直到模板被实例化,实际上是什么基类才知道它;不同的专业可以有不同的成员。所以你必须明确声明它是一个在基类中定义的类型:
template<typename T>
class MyOtherClass: public MyClass<T>
{
typedef typename MyClass<T>::fptr fptr;
// now fptr is available in this class template
};
要访问依赖基类的成员,可以将它们称为MyClass<T>::member
或this->member
。