如何分配函子到函数指针? [英] How to assign functor to function pointer?

查看:139
本文介绍了如何分配函子到函数指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一般来说,我可以将一个函数对象分配给一个函数指针吗?我想做这样的事情:

Generally, can I assign a function object to a function pointer? I want to do something like this:

#include <iostream>

class Foo {
    int num;
public:
    Foo(int num_par) : num(num_par) {}
    void operator()(int multiplier) {
        std::cout << multiplier * num << std::endl;
    }
};

int main() {
    typedef void(*bar)(int);
    Foo f(42);
    bar b = f; // MSVC error
               // ^ C2440: 'initializing' : cannot convert from 'Foo' to 'bar'
    b(2); // wanted to print 84
}

如果这不可能,专门用于Windows编程,其中我要 WindowProc 包含从数据local设置为 WinMain 的状态信息(即不产生全局变量)。分配给 WNDCLASSEX lpfnWndProc 成员时会出现问题。虽然 std :: function 解决了上述代码段的问题:

If that's impossible, I’d like an alternative specifically for Windows programming, where I want WindowProc to contain state information that is set from data local to WinMain’s body (i.e. without making global variables). The problem occurs when assigning to the WNDCLASSEX’s lpfnWndProc member. Though std::function solves the problem for the above snippet:

std::function<void(int)> sf = f;
sf(2); // prints 84

它不适用于我的WinAPI案例:

it doesn't work for my WinAPI case:

class WindowProc {
    int some_state;
public:
    void set_some_state(int par);
    LRESULT CALLBACK operator()(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
};

int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow) {

    HWND hWnd;
    WNDCLASSEX wc;
    WindowProc wp;

    typedef LRESULT(CALLBACK *baz)(HWND, UINT, WPARAM, LPARAM);

    std::function<baz> std_func = wp;
    std::function<baz> std_binded_func = std::bind(&WindowProc::operator(), &wp);

    // none of these compile:
    wc.lpfnWndProc = wp;                      // #1
    wc.lpfnWndProc = wp.operator();           // #2
    wc.lpfnWndProc = &WindowProc::operator(); // #3. Wrong anyway because some_state's value is part of the instance, not the class
    wc.lpfnWndProc = std_func;                // #4. Wrong anyway because some_state's value is part of the instance, not the class
    wc.lpfnWndProc = std_binded_func;         // #5

    // do stuff...
    wp.set_some_state(some_runtime_number);
    // ...do other stuff
}

MSVC 2013错误:

MSVC 2013 Errors:

1。)错误C2440: = :无法转换 WindowProc WNDPROC

1.) error C2440: = : cannot convert from WindowProc to WNDPROC

2。)错误C3867: WindowProc :: operator ):函数调用缺少参数列表;使用& WindowProc :: operator()创建指向成员的指针

2.) error C3867: WindowProc::operator (): function call missing argument list; use &WindowProc::operator () to create a pointer to member

2 cont。)错误C2440: = :无法从 LRESULT(__stdcall WindowProc :: *)(HWND,UINT,WPARAM,LPARAM) code> WNDPROC

2 cont.) error C2440: = : cannot convert from LRESULT (__stdcall WindowProc::* )(HWND,UINT,WPARAM,LPARAM) to WNDPROC

3。)与2 cont。相同

3.) same as '2 cont.'

4。)错误C2440: = :无法从 std :: function< baz> c $ c> WNDPROC

4.) error C2440: = : cannot convert from std::function<baz> to WNDPROC

5。)与4相同。

我可以让它工作吗?

推荐答案

一般来说,函数对象除了要调用的函数之外还包含附加的上下文信息。关于你可以分配给函数指针的唯一函数对象是具有空捕获的lambda函数,但这只是一个函数:

In general, function objects contain additional context information besides the function to be called. About the only function object you can assigned to a function pointer is a lambda function with an empty capture but this is really just a function:

void (*bar)(int) = [](int x) { std::cout << x; }

如果你想通过函数指针得到一个函数对象,你需要希望函数指针有一个合适的参数,可供用户指定并可以直接传递:

If you want to get a function object through a function pointer, you need to hope that the function pointer has a suitable argument which is available for users to specify and which can passed through directly:

void call_function(int arg, void* user_data) {
    (*static_cast<std::function<void(int)>*>(userdata))(arg);
}
...

std::function<void(int)> function_object;
void (*bar)(int, void*) = &call_function;

bar(17, &function_object);

采用函数指针的最合理的现代接口还带有一个用户数据指针,通过必要的上下文。显然,除了通过必要的上下文之外,可能有必要以某种方式维护用作上下文的对象的生命周期。

Most reasonably modern interfaces taking a function pointer also take a user-data pointer which can be used to pass through the necessary context. Obviously, in addition to passing through the necessary context it may be necessary to somehow maintain the life-time of object used as context.

我不是Windows程序员,我猜想你试图使用的API实际上有能力设置一个函数指针和指向一些用户数据的指针。如果没有地方传递上下文信息,您将需要以某种方式在函数指针本身中编码必要的信息。例如,您可以使用引用全局对象的函数指针来获取上下文。显然,对于你想传递的每个上下文,你需要一个不同的函数。

I'm not a Windows programmer but I would guess that the API you are trying to use actually has the ability to set both a function pointer and a pointer to some user data. If there is no place to pass through context information you would need to somehow encode the necessary information in the function pointer itself. For example, you could use a function pointer which references a global object to get the context. Clearly, you would need a different function for each context you want to pass.

这篇关于如何分配函子到函数指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆