【问题标题】:C++ Function Pointer as ArgumentC++ 函数指针作为参数
【发布时间】:2025-12-02 18:45:02
【问题描述】:

我已经尝试了多个谷歌搜索和帮助指南,但我对这个没有想法。我有一个函数指针,用作另一个函数的参数。这两个函数都在同一个类中。但是,我不断收到类型转换错误。我确定这只是一个语法问题,但我不明白正确的语法是什么。这是我的代码的简化版本:

头文件

#ifndef T_H
#define T_H

#include <iostream>
#include <complex>

namespace test
{

class T
{
public:
    T();
    double Sum(std::complex<double> (*arg1)(void), int from, int to);
    int i;
    std::complex<double> func();
    void run();
};

}
#endif // T_H

源文件

#include "t.h"

using namespace test;
using namespace std;

//-----------------------------------------------------------------------
T::T()
{
}

//-----------------------------------------------------------------------
double T::Sum(complex<double>(*arg1)(void), int from, int to)
{
    complex<double> out(0,0);

        for (i = from; i <= to; i++)
        {
            out += arg1();
            cout << "i = " << i << ", out = " << out.real() << endl;
        }

    return out.real();
}

//-----------------------------------------------------------------------
std::complex<double> T::func(){
    complex<double> out(i,0);
    return out;
}

//-----------------------------------------------------------------------
void T::run()
{
    Sum(&test::T::func, 0, 10);
}

每当我尝试编译时,都会收到以下错误:

no matching function for call to 'test::T::Sum(std::complex<double> (test::T::*)(),int,int)'
note:  no known conversion for argument 1 from 'std::complex<double> (test::T::*)()' to 'std::complex<double>(*)()'

任何建议表示赞赏。或者至少是一个关于如何使用函数指针的完整站点的链接。我正在使用 Qt Creator 2.6.2,使用 GCC 编译。

【问题讨论】:

  • 这不仅仅是任何旧功能。它是一个 member 函数。
  • complex&lt;double&gt;(*arg1)(void) 更改为complex&lt;double&gt;(T::*arg1)(void)
  • 我相信你会这样称呼它out += (this-&gt;*arg1)();

标签: c++ function pointers arguments


【解决方案1】:

您的 Sum 函数需要指向函数的指针。然后你尝试用一个指向成员函数的指针来调用它。了解指向成员的指针。

【讨论】:

    【解决方案2】:

    代码本身有点乱,我只会更正语法使其正常工作。

    首先,你应该改变函数原型

    double Sum(std::complex<double> (*arg1)(void), int from, int to);
    

    double Sum(std::complex<double> (T::*arg1)(void), int from, int to);
    

    表示它是指向类 T 的成员的指针。

    那么,调用函数的时候,不能只用arg1()

    for (i = from; i <= to; i++)
    {
        out += arg1();
        cout << "i = " << i << ", out = " << out.real() << endl;
    }
    

    你必须使用(this-&gt;*arg1)();

    for (i = from; i <= to; i++)
    {
        out += (this->*arg1)();
        cout << "i = " << i << ", out = " << out.real() << endl;
    }
    

    【讨论】:

    • 现在代码不再支持传递普通函数的普通用例了。
    • 好点。目前,我只需要它为成员函数工作。在以后的版本中,我可能会添加一个重载以允许正常功能。可能作为最大灵活性的模板函数。但是在这之后我还有几千行代码要调试。现在,我打算保持简单。
    【解决方案3】:

    如何在 C++ 中将函数作为参数传递?一般来说,使用模板,除非您有非常令人信服的理由不这样做。

    template<typename Func>
    void f(Func func) {
      func(); // call
    }
    

    在调用端,您现在可以抛出一定数量的对象(不仅仅是指向函数的指针):

    函子;

    struct MyFunc {
      void operator()() const {
        // do stuff
      }
    };
    
    // use:
    f(MyFunc());
    

    普通函数:

    void foo() {}
    
    // use
    f(&foo) {}
    

    会员功能:

    struct X {
      void foo() {}
    };
    
    // call foo on x
    #include <functional>
    X x;
    func(std::bind(&X::foo, x));
    

    Lambda:

    func([](){});
    

    如果你真的想要编译函数而不是模板,请使用std::function

    void ff(std::function<void(void)> func) {
      func();
    }
    

    【讨论】:

    • 原来我需要学习如何使用指向成员函数的指针。我也喜欢使用允许 lambda 的模板的想法。我之前尝试过 lambda,但遇到了编译器错误。我认为目前,我将简单地编写函数以允许指向成员函数的指针。在以后的版本中,我可能会添加一个重载,它使用 Sum() 作为模板函数来允许 lambda。谢谢大家的好建议。
    • @NicholasBarczak 您可能想检查您的编译器是否支持 C++11。 gcc 4.7 以上确实,clang 3.3 以上也是如此。两者都需要传递 -std=c++11 参数。 MSVC 有点支持它,但是版本和编译器预发行版本很乱,什么都不支持。