我试图让一个类函数接受另一个类未知函数。我希望这是有道理的。我想做的是...如果单击 button1(或任何声明的按钮),它将执行输入到函数 Event__MouseClicked 的第一个参数中的任何函数(任何“无效函数”)。
bool MouseClicked( void ){ /**/ };
namespace XE
{
class Window
{
public:
const char* Title;
};
class Button
{
public:
void Event__MouseClicked( void( *Function )( void ) ) {
if( MouseClicked( ) )
( *Function )( );
}
};
};
class XorrWindow1 : public XE::Window
{
public:
XorrWindow1( void ) {
Initialize( );
}
protected:
~XorrWindow1( void );
private:
XE::Button Button1;
XE::Button Button2;
private:
// EVENT PROTOTYPES
void DoSomething( void );
void RandomFunction( void );
void Initialize( void )
{
// INITIALIZE CONTROLS
// AND OTHER STUFF BELOW
this->Title = "XorrWindow1";
// How can I resolve this problem?
this->Button1.Event__MouseClicked( &XorrWindow1::DoSomething );
this->Button2.Event__MouseClicked( &XorrWindow1::RandomFunction );
};
};
void XorrWindow1::DoSomething( void ) {
::MessageBoxA( NULL, this->Title, "Button1 clicked!", MB_OK );
};
void XorrWindow1::RandomFunction( void ) {
::MessageBoxA( NULL, this->Title, "Button2 clicked!", MB_OK );
};
错误是这样的:
'XE::Button::Event__MouseClicked' : cannot convert parameter 1 from 'void (__thiscall XorrWindow1::* )(void)' to 'void (__cdecl *)(void)'
我完全明白是什么导致了错误。但我不知道如何修复它,因为它必须能够接受 Window1 类的任何未知函数。
最佳答案
正如 Karel Petranek 所说,您需要模板来适应所有情况。这是最的通用方法(STL 无处不在):
template<typename f>
void Event__MouseClicked(f&& func)
{
if( MouseClicked( ) )
func();
}
基本上 Event__MouseClicked
接受一个可调用对象。在你的情况下,你会像 Marcelo Cantos 描述的那样调用它:
Button1.Event__MouseClicked([&]{ DoSomething(); });
但此方法的好处是,将任何 不带参数的可调用对象传递给Event__MouseClicked
将编译并运行。您可以传递函数指针、std::bind
的结果、std::function
、lambda 等。
在某些情况下,这比强行接受 std::function
更优化,例如当接受直接函数指针时。
关于C++ 将类型作为未知类函数的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14429495/