【问题标题】:function pointers using functions in an object with parameters使用带参数的对象中的函数的函数指针
【发布时间】:2015-04-08 04:21:30
【问题描述】:

我一直在使用 c++ 中的函数指针,似乎发现了一些问题。我做了一个demo,用一个简单的例子重现了这个错误。

我有头文件

class MyClass
{
public:
    void MyFunction(int i);
    MyClass();
    ~MyClass();
};

和cpp文件

#include "MyClass.h"
#include <iostream>
#include <functional>
using namespace std;

MyClass::MyClass()
{
    //doesn't work
    function<void(int)> func = &MyClass::MyFunction;
}

void MyClass::MyFunction(int i)
{
    cout << i << endl;
}

在 cpp 文件的构造函数中,我试图创建一个指向 MyFunction 的指针。它在第 506 行的功能文件中给出了错误error C2664: 'void std::_Func_class&lt;_Ret,int&gt;::_Set(std::_Func_base&lt;_Ret,int&gt; *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base&lt;_Ret,int&gt; *'。它适用于无参数方法,但不适用于它们。有谁知道为什么,以及如何解决?

【问题讨论】:

  • 非静态成员函数需要一个对象。
  • 所以我不能在课堂上做到这一点?或者有没有办法用我完全错过的 this 关键字来做到这一点?

标签: c++ function pointers


【解决方案1】:

您可以使用this 并将正在构造的对象绑定到函数。例如,如果您的构造函数如下所示:

MyClass::MyClass()
{
    function<void(int)> func = bind(&MyClass::MyFunction, this, placeholders::_1);
    func(6);
}

你创建了一个MyClass 实例:

MyClass instance;

然后6 将被打印到标准输出。

【讨论】:

  • 这行得通,谢谢。你能解释一下 placeholders::_1 是什么吗?
  • 占位符基本上是作为currying函数的一种方式。所有非静态成员函数实际上都有一个隐式的第一个参数,即类本身的一个实例。您正在做的是将实例绑定到第一个参数,而第二个参数未指定。占位符为您提供表达这一点的语义。
  • 例如,如果你用6代替占位符,那么函数将被完全指定,你只能将它称为func()。这会将6 打印到标准输出。
【解决方案2】:

也可以在 C++11 中使用std::mem_fn,它将成员函数/变量包装到可调用闭包中

#include <iostream>
#include <functional>

class MyClass
{
public:
    MyClass()
    {
        auto func = std::mem_fn(&MyClass::MyFunction);
        func(this, 42); // call it on the current instance
    }
    void MyFunction(int i)
    {
        std::cout << i << std::endl;
    }
};

int main()
{
    MyClass foo;
}

或者,您可以显式指定要调用的实例,指向成员函数的指针

MyClass()
{
    auto func = &MyClass::MyFunction;
    (this->*func)(42); // call it on the current instance
}

特别注意std::function&lt;void(int)&gt; 不能转换为指向成员函数的指针。见相关Using generic std::function objects with member functions in one class 这就是为什么使用 autostd::mem_fn 可以摆脱所有痛苦。

【讨论】:

  • 这是一个很好的答案。它让您可以像对待 C++ 一样对待函数,将类的实例作为第一个参数,然后将所有其他参数作为函数。
  • 谢谢,我最近才发现 std::mem_fn,我认为它是日常 C++ 工作的绝佳包装
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-03
  • 2018-01-03
  • 1970-01-01
相关资源
最近更新 更多