Skip to content

Instantly share code, notes, and snippets.

@carmel4a
Last active September 1, 2018 09:17
Show Gist options
  • Save carmel4a/2e07a532837dcaa18ab6cfca291cd956 to your computer and use it in GitHub Desktop.
Save carmel4a/2e07a532837dcaa18ab6cfca291cd956 to your computer and use it in GitHub Desktop.
Example of field in a class `Button`, where we may contain reference to any other class member function.
#include <iostream>
#include <functional>
// In "some classes" you wanna have some functions.
struct SomeClass
{
void f1( int a )
{
std::cout<< a << std::endl;
};
void f2( int a, float b)
{
std::cout<< a << " "<< b << std::endl;
};
void f3()
{
std::cout<<"void" << std::endl;
};
};
template< typename T, typename... Args >
struct FunctionHandler
{
std::function<void( T*, Args ... args )> function;
};
/*
template< typename... Args >
struct FunctionHandler
{
std::function<void( Args ... args )> function;
};
*/
// here's your button
class Button
{
public:
void* handler; // NOPE ;/
template< class T, typename... Args >
void bind_function( void(T::*&&f )( Args ... args ) )
{
auto* p = new FunctionHandler< T, Args ... >(); // here we create content of this pointer
handler = p;
p->function = ( std::function<void( T*, Args ... args )> )f; // bind a function. We may use std::bind() as well. NOTE: we want get address of function in class, not object,
}
template< class T, typename... Args >
void call_function( T& t, Args ... args )
{
auto* p = ( FunctionHandler< T, Args ... >* ) ( handler ); // Here we cast a void pointer.
(*p).function( &t, args ... ); // here we call that function
}
template< class T, typename... Args >
void unbind_function()
{
auto* p = ( FunctionHandler< T, Args ... >* ) (handler); // Here we cast a void pointer.
delete p; // delete helper
handler = nullptr; // set ptr to null;
}
};
int main()
{
Button b; // create some buttons
SomeClass o; // create some object. It should work with static objects, or even static class members (if so, you should change template a bit).
// Set first function
b.bind_function< SomeClass, int >( &SomeClass::f1 );
b.call_function< SomeClass, int >( o, 1 );
b.unbind_function< SomeClass, int >();
b.bind_function< SomeClass, int, float >( &SomeClass::f2 );
b.call_function< SomeClass, int, float >( o, 1, 2.0f );
b.unbind_function< SomeClass, int, float >();
b.bind_function< SomeClass >( &SomeClass::f3 );
b.call_function< SomeClass >( o );
b.unbind_function< SomeClass >();
return 0;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment