5

在 C++ 中可能吗?例如,我有一个指向不带参数的函数的指针,它的返回类型为 void:

void (*f)();

和一个函数对象:

class A
{
public:
    void operator()() { cout << "functor\n"; }
};

是否可以分配给对象f的地址A?当我打电话f()A函子时?

我试过这个但它不起作用:

#include <iostream>
using namespace std;

class A
{
public:
    void operator()() { cout << "functorA\n"; }
};

int main()
{
    A ob;
    ob();
    void (*f)();
    f = &ob;
    f();       // Call ob();
    return 0;
}

我明白了C:\Users\iuliuh\QtTests\functor_test\main.cpp:15: error: C2440: '=' : cannot convert from 'A *' to 'void (__cdecl *)(void)' There is no context in which this conversion is possible

有什么办法可以做到这一点?

4

4 回答 4

5

您不能按照您指定的方式进行操作,因为:

  1. operator() 必须是非静态函数(标准要求)
  2. 指向非静态函数的指针必须有一个隐式参数——指向类实例的指针
  3. 您对 f() 的调用并没有说明您的函数被调用的对象 A 的哪个实例

正如 Stephane Rolland 所指出的,使用 C++11 和 std::function 可以解决问题 - 您将在绑定中指定指向对象的指针:

std::function<void(void)> f = std::bind(&A::operator(), &ob);

(请参阅有关在成员函数上使用 std::function 的问题)

于 2013-02-01T09:35:27.453 回答
3

如果你使用 C++11,可以使用std::function

#include <functional>

std::function<void()> f;

int main()
{
    A ob;
    ob();

    f = ob;    // f refers to ob
    f();       // Call ob();
    return 0;
}
于 2013-02-01T09:39:35.563 回答
2

是的,使用 C++1/C++0x 功能是可能的,但要实现这一点,您应该使用std::function可以寻址两种类型,函数和对象函数。

#include <functional>

 class A
{
public:
    void operator()() { }
};

int main()
{
    std::function<void(void)> aFunction;
    A ob;

    aFunction = ob;

// or as another user said
// aFunction = std::bind(&A:operator(), &ob);

    aFunction();

    void (*f)();

    aFunction = f;

    aFunction();

    return 0;
}

如果你坚持使用 C++03,你可以std::mem_funstd::ptr_fun

于 2013-02-01T09:28:50.017 回答
1

像这样的一些解决方法怎么样:

基本上你希望有一种调用成员函数和函数的通用方式。然后也许你可以创建一个包装器来表示一个指向函数或成员函数的通用指针。假设您有Base类,并且希望能够调用operator()所有派生类。然后你也有一个function()你想要调用的:

class Base
{
public:
    virtual void operator()() = 0;
};

class A : public Base
{
public:
    void operator()(){ std::cout << "A()" << std::endl; }
};

void function()
{
    std::cout << "function" << std::endl; 
}

如果您创建一个允许您构造自定义指针 ( MyFncPtr) 的包装器:

typedef void (Base::*BaseFncPtr)();
typedef void (*FncPtr)();

class MyFncPtr
{
public:
    MyFncPtr(FncPtr f) : fnc(f), baseObj(NULL), baseFnc(NULL) { }
    MyFncPtr(BaseFncPtr fPtr, Base* objPtr) : baseFnc(fPtr), baseObj(objPtr), fnc(NULL)  { }
    void invoke()
    {
        if (baseObj && baseFnc)
            (baseObj->*baseFnc)();
        else if (fnc)
            fnc();
    }

private:
    BaseFncPtr baseFnc;
    Base* baseObj;
    FncPtr fnc;
};

你可以像这样实现它:

A a;
MyFncPtr myPtr(&Base::operator(), &a);
myPtr.invoke();
MyFncPtr myPtr2(function);
myPtr2.invoke();

输出:

A()
function

希望这可以帮助 :)

于 2013-02-01T10:24:57.897 回答