X11库中的XSetErrorHandler()函数需要一个函数。
如果我在main()[in main.cpp]上面定义了一个函数,比如:
int catch_error(Display *disp, XErrorEvent *xe){return 0;}
然后我做以下操作:
XSetErrorHandler(catch_error);
它起作用了。
如何将catch_error函数放在名为WindowHandler的类中,然后将其传递给XSetErrorHandler();
我尝试了以下方法:
WindowHandler window_handler = new WindowHandler();
XSetErrorHandler(WindowHandler::catch_error);
XSetErrorHandler(window_handler->catch_error);
XSetErrorHandler((*window_handler).catch_error);
型
错误1)类型为“int(WindowHandler::*)(Display *disp,XErrorEvent *xe)”的参数与类型为“XErrorHandler”的参数不兼容
2)和3)指向绑定函数的指针只能用于调用该函数
谢谢你的帮忙!
1条答案
按热度按时间vuv7lop31#
问题是非静态成员函数需要一个隐式的第一个参数,这个参数是指向类 (在本例中是
WindowHandler
) 的指针或引用,所以如果我们考虑到隐式参数,那么它的签名与自由的catch_error
函数不同。我不知道
XSetErrorHandler
是如何声明的,但是这个函数可以接受函子:在这种情况下,可以将对WindowHandler::catch_error
的调用 Package 在一个lambda表达式中,该表达式捕获指向WindowHandler
示例的指针。下面是关于指向成员函数的指针的一些进一步的阅读:https://isocpp.org/wiki/faq/pointers-to-members
编辑:
我刚刚意识到,
XSetErrorHandler
不接受函子,而只接受函数指针https://tronche.com/gui/x/xlib/event-handling/protocol-errors/XSetErrorHandler.html。在这种情况下,WindowHandler::catch_error
必须是静态的。如果lambda没有捕获任何内容,则只能将其视为函数指针。如果你真的想在
WindowHandler
的一个成员中捕获error_flag
,我看到的唯一选择是拥有WindowHandler
* 的一个全局示例(所谓的单例)*,然后静态catch_error
函数可以设置这个单例的成员,不需要隐式的this
参数。注意,不鼓励使用全局变量和单例变量,如果可能的话,应该避免使用。在某些情况下,这是不可能的。在这些情况下,通常需要日志记录和错误处理。
https://godbolt.org/z/MTWcfK3bs