【问题标题】:How to pass a virtual function as an argument in C++? [duplicate]如何在 C++ 中将虚函数作为参数传递? [复制]
【发布时间】:2022-09-21 17:55:02
【问题描述】:

我正在尝试在下面编写此代码:

// Type your code here, or load an example.
#include <iostream>

class A
{
public:
    virtual void virFunc1(int a) = 0;
    virtual void virFunc2(int a) = 0;
    void func1(int a)
    {
        onTempFunc(this->virFunc1, a);
    }
    void func2(int a)
    {
        onTempFunc(this->virFunc2, a);
    }
private:
    template <typename ImplFunc, typename... Args>
    void onTempFunc(ImplFunc impl_func, Args&&... args)
    {
        impl_func(args...);
    }
};

class B : public A
{
public:
    void virFunc1(int a) override
    {
        std::cout << \"virFunc1: \" << a << std::endl;
    }

    void virFunc2(int a) override
    {
        std::cout << \"virFunc2: \" << b << std::endl;
    }
};

int main()
{
    auto* A = new B();
    A->func1(2);
    A->func2(3);
}

但是在 Godbolt 中编译失败:https://godbolt.org/z/dq4szorq7 并出现错误:error: invalid use of non-static member function \'virtual void\'。基本上我想将虚拟方法及其参数传递给函数模板。函数模板将在其中调用该虚拟方法。不同的虚方法可以有不同的函数签名,这就是我将onTempFunc作为函数模板的原因。 C++ 有没有办法做到这一点?

标签: c++ polymorphism c++17


【解决方案1】:

virFunc1virFunc2 作为参数传递的正确语法是分别编写&amp;A::virFunc1&amp;A::virFunc2,如下所示。

此外,为了调用/使用传递的成员函数指针,我们可以使用-&gt;*,如下所示:

class A
{
public:
    virtual void virFunc1(int a) = 0;
    virtual void virFunc2(int a) = 0;
    void func1(int a)
    {
//-----------------vvvvvvvvvvvv-------->changed this
        onTempFunc(&A::virFunc1, a);
    }
    void func2(int a)
    {
//-----------------vvvvvvvvvvvv------->changed this 
        onTempFunc(&A::virFunc2, a);
    }
private:
    template <typename ImplFunc, typename... Args>
    void onTempFunc(ImplFunc impl_func, Args&&... args)
    {
//-------vvvvvvvvvvvvvvvvvvvvvvvvvv------> used ->* for member function pointer
        (this->*impl_func)(args...);
    }
};

Working demo

另请参阅Passing functions as parameters in C++

【讨论】:

  • 另外,我有一个相关的问题。我应该使用std::forward 在这里转发参数吗?
  • @In78 是的,如果要保留原始传递参数的值类别,可以使用 std::forward。更详细的解释请参考Why should I use std::forward?
【解决方案2】:

您可以使用成员函数指针。

这个

onTempFunc(this->virFunc1, a);

获取成员函数指针的语法不正确。和这个

impl_func(args...);

通过成员函数指针调用成员函数的语法不正确。

指向virFunc1 的成员函数指针是&amp;A::virFunc1。您可以通过(this-&gt;*impl_func)(args...); 调用它:

class A
{
public:
    virtual void virFunc1(int a) = 0;
    virtual void virFunc2(int a) = 0;
    void func1(int a)
    {
        onTempFunc(&A::virFunc1, a);
    }
    void func2(int a)
    {
        onTempFunc(&A::virFunc2, a);
    }
private:
    template <typename ImplFunc, typename... Args>
    void onTempFunc(ImplFunc impl_func, Args&&... args)
    {
        (this->*impl_func)(args...);
    }
};

Live Demo

【讨论】:

    猜你喜欢
    • 2015-09-28
    • 2022-01-24
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    • 2015-11-08
    • 2020-02-10
    相关资源
    最近更新 更多