【问题标题】:How to use typedef from template base class in Ctor of the Derived?如何在派生的 Ctor 中使用模板基类中的 typedef?
【发布时间】:2018-10-09 15:41:26
【问题描述】:

如果我有一个两个模板的基类和一个派生类:

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();
    }
};

派生类需要将函数指针传递给Ctor中的基类。看完Inheritance and templates in C++ - why are methods invisible?我明白了,应该按如下方式调用Ctor中的typedef:

Derived(Base<D>::func f) : Base<D>(f) {};

但是,当我尝试编译时:

int returnZero(){
    return 0;
}

Derived<int> d(returnZero);
std::cout << d.foo() << std::endl;

我明白了:

  error: expected ')' before 'f'
  Derived(Base<D>::func f) : Base<D>(f) { };
                        ^
cpp_code.cpp: In function 'int main()':
cpp_code.cpp:59:27: error: no matching function for call to 'Derived<int>::Derived(int (&)())'
  Derived<int> d(returnZero);
                           ^
cpp_code.cpp:47:7: note: candidate: constexpr Derived<int>::Derived(const Derived<int>&)
 class Derived : public Base<D> {
       ^~~~~~~
cpp_code.cpp:47:7: note:   no known conversion for argument 1 from 'int()' to 'const Derived<int>&'
cpp_code.cpp:47:7: note: candidate: constexpr Derived<int>::Derived(Derived<int>&&)
cpp_code.cpp:47:7: note:   no known conversion for argument 1 from 'int()' to 'Derived<int>&&'

在Ctor中使用函数指针(func)的正确方法是什么?

【问题讨论】:

    标签: c++ templates inheritance


    【解决方案1】:

    Clang 通常会给出一个非常有用的错误消息来解释一切:

    error: missing 'typename' prior to dependent type name 'Base<D>::func'
        Derived(Base<D>::func f) : Base<D>(f) { };
                ^~~~~~~~~~~~~
                typename 
    

    如果从属名称是类型或模板,则应分别使用 typenametemplate 关键字来消除歧义。

    这是必需的,因为在 Derived 定义中,编译器不知道将使用什么类型而不是 D,因此由于可能的专业化,它不知道 Base&lt;D&gt; 的实际定义是什么.这就是为什么 Base&lt;D&gt; 中的任何标识符都依赖类型 D

    然而,编译器仍然需要能够解析它只能部分理解的代码,这就是为什么你需要告诉它标识符func不仅仅是Base&lt;D&gt;的成员,而是一个typename,因为它定义了可以使用此标识符的上下文。


    附带说明: 有一个proposal 可以摆脱这个烦人的规则,用于只能使用类型的上下文,比如你的。

    【讨论】:

      猜你喜欢
      • 2016-02-02
      • 2018-11-09
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 2014-09-23
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      相关资源
      最近更新 更多