【问题标题】:error in child class definition of templated class inheritance模板类继承的子类定义错误
【发布时间】:2019-12-14 01:01:53
【问题描述】:

我正在定义可以将函数作为模板参数的类AB 类继承 A 类。但是,有错误B: use of class template requires template argument list 和多个其他错误。我在想B 类的声明出错了。但是,我没有为 B 类使用任何模板。有人可以评论吗?

#include <iostream>

void f_global()
{
    std::cout << "top level function\n";
}

template<typename F>
class A
{
public:
    F f1;
    A(F fun1) : f1(fun1) {}
    void fa();
};

template<typename F>
void A<F> :: fa()
{
    std::cout << "From A<F>::fa()\n";
    f1();
}

template<typename F>
class B : public A<F> //error
{
public:
    void fb();
};

void B::fb() //error
{
    std::cout << "From B::fb()\n";
    A::f1(); //Can access f1()?
}
int main()
{
    A obja(f_global); //error?
    obja.fa();
    B objb;
    objb.fb();
}

【问题讨论】:

  • 就像你对template&lt;typename F&gt; void A&lt;F&gt; :: fa() 做的一样,你需要对void B::fb() 做同样的事情。您还有很多其他语法/错字错误。
  • 此外,由于模板 A 没有默认构造函数,因此无法构造模板 B,模板 B 期望其超类具有默认构造函数。这里有一些模板使用的基本问题。
  • 你说“我没有使用B类的任何模板”,但你是; template&lt;typename F&gt; class B ... 表示 B 是一个模板。
  • 你想让B成为一个模板类吗?也许是 A 的专业化?
  • 在你的 main 中,你调用了 f2,但是 f2() 在哪里?

标签: c++ class templates c++17


【解决方案1】:

首先,解释您要达到的目标通常很有用。这里有很多非常聪明的人,他们会为你的问题想出与你完全无关的解决方案。

现在,我试图猜测您想要实现的目标。由于您从fb 调用fa,我假设Btemplate。如果不是,那么至少 fb 应该是一个模板函数。但是,由于您没有将要执行的函数作为参数传递给fb,所以我终于猜到您的class B 打算成为template

所以,你的全局函数没问题:

void f_global()
{
    std::cout << "top level function\n\n";
}

您的class A 没问题,但为了清楚起见,我将F 用作函数类型,将F* 用作函数指针(*),我还将function 存储为@987654334 @ 成员。但是,为了尊重您问题中的代码,我将其保留为 public 成员。

编辑 (*) 正如@Phil1970 指出的那样,FF* 更通用,因为它适用于 lambdas 和 std::function

template <typename F>
class A
{
public:
    A(F fun) : _f {fun} {}
    void fa() { std::cout << "From A<F>::fa()\n"; _f(); }
    F _f;
};

如您所见,您的class B 存在问题。首先,如果template &lt;typename F&gt; B继承自template &lt;typename F&gt; A,你应该可以在B&lt;F&gt;的构造函数中构造一个A&lt;F&gt;类型的对象。换句话说,B&lt;F&gt; 应该能够构造A&lt;F&gt;,因此,您应该将函数f_global 传递给class B&lt;F&gt; 的构造函数。

template <typename F>
class B : public A<F>
{
public:
    B(F* fun) : A<F>(fun) {}
    void fb() { std::cout << "From B::fb()\n"; A<F>::_f(); }
    void fb1() { std::cout << "From B::fb1()\n"; this->template _f(); }
    using A<F>::_f;
    void fb2() { std::cout << "From B::fb2()\n"; _f(); }
};

我添加了函数fb1fb2 来向您展示如何使用模板推导和关键字using 调用可调用的_f 成员。

【讨论】:

  • 是否可以在 C++17 中使用自动模板检测功能而不是指定指针?
  • 如果您的意思是如果构造函数可以采用 F 类型的函数而不是 F*,那么答案是肯定的。然后将 F 推导出为 void (*)()。在我的例子中,F 被推断为 void ()。在这两种情况下,参数 fun 都是指向 f_global 的指针。
  • @ewr3243 我编辑了问题以保留问题的原始格式。
  • F 而不是 F* 更通用,因为它适用于 std::function 和 lambdas。还是我错过了什么?
  • @MFnx 如问题所述,void B::fb() 是否正确,您能否评论 main() 创建类对象?
猜你喜欢
  • 1970-01-01
  • 2015-02-27
  • 2011-11-30
  • 2020-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多