Last active
September 1, 2018 09:17
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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