[英]How to assign functor to function pointer?
通常,我可以将功能对象分配给功能指针吗? 我想做这样的事情:
#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
包含从WinMain
主体的本地数据设置的状态信息(即,不创建全局变量)。 分配给WNDCLASSEX
的lpfnWndProc
成员时,会发生此问题。 尽管std::function
解决了上述代码段的问题:
std::function<void(int)> sf = f;
sf(2); // prints 84
它不适用于我的WinAPI案例:
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错误:
1.)错误C2440: =
:无法从WindowProc
转换为WNDPROC
2.)错误C3867: WindowProc::operator ()
:函数调用缺少参数列表; 使用&WindowProc::operator ()
创建指向成员的指针
2续)错误C2440: =
:无法从LRESULT (__stdcall WindowProc::* )(HWND,UINT,WPARAM,LPARAM)
WNDPROC
LRESULT (__stdcall WindowProc::* )(HWND,UINT,WPARAM,LPARAM)
为WNDPROC
3.)与“ 2续”相同。
4.)错误C2440: =
:无法从std::function<baz>
转换为WNDPROC
5.)与4。
我如何使它工作?
通常,功能对象除要调用的功能外还包含其他上下文信息。 可以分配给函数指针的唯一函数对象是带有空捕获的lambda函数,但这实际上只是一个函数:
void (*bar)(int) = [](int x) { std::cout << x; }
如果要通过函数指针获取函数对象,则需要希望函数指针具有合适的参数,用户可以指定该参数并且可以直接传递该参数:
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);
最合理的带有函数指针的现代接口也带有用户数据指针,该数据可用于传递必要的上下文。 显然,除了传递必要的上下文外,可能还需要以某种方式保持用作上下文的对象的生命周期。
我不是Windows程序员,但我想您尝试使用的API实际上可以设置函数指针和指向某些用户数据的指针。 如果没有地方可以传递上下文信息,则需要以某种方式在功能指针本身中编码必要的信息。 例如,您可以使用引用全局对象的函数指针来获取上下文。 显然,对于要传递的每个上下文,您将需要一个不同的功能。
您需要以通常的方式声明一个指向成员函数的指针,然后调用它。 尝试这个:
#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(Foo::*bar)(int);
Foo f(42);
bar b = &Foo::operator(); // no more MSVC error
// ^ C2440: 'initializing' : cannot convert from 'Foo' to 'bar'
(f.*b)(2); // wanted to print 84, and it does
}
您必须通过实例进行调用,在此示例中为f
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.