Created
July 17, 2014 02:18
-
-
Save suxue/0eaac4aa6050797fcd82 to your computer and use it in GitHub Desktop.
wrap a function pointer in c++
This file contains hidden or 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
// create an equivalent functor that call the function pointer and print | |
// all input arguments | |
#include <boost/function_types/parameter_types.hpp> | |
#include <boost/function_types/result_type.hpp> | |
#include <boost/mpl/size.hpp> | |
#include <boost/mpl/pop_front.hpp> | |
#include <functional> | |
#include <utility> | |
#include <iostream> | |
using namespace boost::mpl; | |
using namespace boost::function_types; | |
using namespace std; | |
template< typename Arg, typename... Args > | |
void write(Arg&& arg) | |
{ | |
cout << forward<Arg>(arg) << endl; | |
} | |
template< typename Arg, typename... Args > | |
void write(Arg&& arg, Args&&... args ) | |
{ | |
write(forward<Arg>(arg)); | |
write(forward<Args>(args)...); | |
} | |
template<typename FuncPtr, typename... Args> | |
struct Wrapper { | |
FuncPtr funcptr; | |
Wrapper(FuncPtr funcptr) : funcptr(funcptr) {} | |
typename result_type<FuncPtr>::type operator()(Args... args) { | |
cout << "funccall:" << endl; | |
write(forward<Args>(args)...); | |
cout << "end funccall:" << endl; | |
return funcptr(forward<Args>(args)...); | |
} | |
}; | |
template<typename FUNCPTR, int size, typename PARALIST, typename... Args> | |
struct Transformer__ { | |
typedef typename Transformer__<FUNCPTR, size-1, | |
typename pop_front<PARALIST>::type, | |
typename at_c<PARALIST, 0>::type, Args...>::type type; | |
}; | |
template<typename FUNCPTR, typename PARALIST, typename... Args> | |
struct Transformer__<FUNCPTR, 0, PARALIST, Args...> { | |
typedef Wrapper<FUNCPTR, Args...> type; | |
}; | |
template<typename FUNCPTR> | |
struct Transformer { | |
typedef typename parameter_types<FUNCPTR>::type para_t; | |
typedef typename Transformer__<FUNCPTR, size<para_t>::value, para_t>::type type; | |
}; | |
int test(int i, int j) | |
{ | |
return i + j; | |
} | |
int main() | |
{ | |
auto *p = &test; | |
Transformer<decltype(p)>::type wrapper(p); | |
return wrapper(1,2); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment