Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在派生类的Ctor中使用模板基类中的typedef?_C++_Templates_Inheritance - Fatal编程技术网

C++ 如何在派生类的Ctor中使用模板基类中的typedef?

C++ 如何在派生类的Ctor中使用模板基类中的typedef?,c++,templates,inheritance,C++,Templates,Inheritance,如果我有一个基类和一个派生类,这两个模板都是: template <typename T> class Base { public: typedef T (*func)(); Base(func f):m_f(f){}; T invoke(){ return m_f();}; private: func m_f; }; template <typename D> class Derived : public Base<D> {

如果我有一个基类和一个派生类,这两个模板都是

template <typename T>
class Base {
public:
    typedef T (*func)();
    Base(func f):m_f(f){};
    T invoke(){ return m_f();};
private:
    func m_f;
};

template <typename D>
class Derived : public Base<D> {
public:
    Derived(Base<D>::func f) : Base<D>(f) { };
    D foo() {
        return Base<D>::invoke();
    }
};
模板
阶级基础{
公众:
typedef T(*func)();
基(func f):m_f(f){};
T invoke(){return m_f();};
私人:
func m_f;
};
模板
派生类:公共基{
公众:
派生的(Base::func f):Base(f){};
D foo(){
返回Base::invoke();
}
};
派生类需要传递一个函数指针到Ctor中的基。阅读后,我了解到应按以下方式调用Ctor中的typedef:

Derived(Base<D>::func f) : Base<D>(f) {};
Derived(Base::func f):Base(f){};
但是,当我尝试编译时:

int returnZero(){
    return 0;
}

Derived<int> d(returnZero);
std::cout << d.foo() << std::endl;
int returnZero(){
返回0;
}
导出d(返回零);

std::coutclangas通常会给出一条非常有用的错误消息,解释一切:

error: missing 'typename' prior to dependent type name 'Base<D>::func'
    Derived(Base<D>::func f) : Base<D>(f) { };
            ^~~~~~~~~~~~~
            typename 
错误:在依赖类型名称“Base::func”之前缺少“typename”
派生的(Base::func f):Base(f){};
^~~~~~~~~~~~~
字体名
如果从属名称是类型或模板,则应分别使用
typename
template
关键字消除歧义

这是必需的,因为在
派生的
定义中,编译器不知道将使用什么类型来代替
D
,因此由于可能的专门化,它不知道
Base
的实际定义是什么。这就是为什么
Base
中的任何标识符都依赖于类型
D

然而,编译器仍然需要能够解析它只能部分理解的代码,这就是为什么您需要帮助它,告诉它标识符
func
不仅仅是
Base
的成员,而是
typename
,因为这定义了可以使用该标识符的上下文。

另一方面:对于只能使用类型的上下文,例如您的上下文,有一种方法可以消除这种恼人的规则。

叮当声通常会给出一条非常有用的错误消息,解释一切:

error: missing 'typename' prior to dependent type name 'Base<D>::func'
    Derived(Base<D>::func f) : Base<D>(f) { };
            ^~~~~~~~~~~~~
            typename 
错误:在依赖类型名称“Base::func”之前缺少“typename”
派生的(Base::func f):Base(f){};
^~~~~~~~~~~~~
字体名
如果从属名称是类型或模板,则应分别使用
typename
template
关键字消除歧义

这是必需的,因为在
派生的
定义中,编译器不知道将使用什么类型来代替
D
,因此由于可能的专门化,它不知道
Base
的实际定义是什么。这就是为什么
Base
中的任何标识符都依赖于类型
D

然而,编译器仍然需要能够解析它只能部分理解的代码,这就是为什么您需要帮助它,告诉它标识符
func
不仅仅是
Base
的成员,而是
typename
,因为这定义了可以使用该标识符的上下文。
另一方面:对于只能使用类型的上下文(例如您的上下文),有一个方法可以消除这个恼人的规则