1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
#include <iostream>
#include <functional>
namespace detail
{
template < typename T, typename R, typename... A > struct ptr_fun
{
template < R (T::*PMFN)(A...) > struct fun_maker
{
static R fun( T* p, A... args ) { return (p->*PMFN)(args...) ; }
static auto ptr() { return &fun ; }
};
template < R (T::*PMFN)(A...) const > struct fun_maker_c
{
static R fun( const T* p, A... args ) { return (p->*PMFN)(args...) ; }
static auto ptr() { return &fun ; }
};
};
}
struct A
{
double foo( int a, char b ) { std::cout << "A::foo(int,char)\n" ; return double(a) + b ; }
int bar( short a, char b, char c ) const { std::cout << "A::bar(short,char,char) const\n" ; return int(a) + b + c ; }
};
int main()
{
// pointer to free function
const auto pfn_foo = detail::ptr_fun< A, double, int, char >::fun_maker< &A::foo >::ptr() ;
// call wrapper
const auto foo_wrapped = std::function< double( A*, int, char ) >( &A::foo ) ;
// pointer to free function
const auto pfn_bar = detail::ptr_fun< A, int, short, char, char >::fun_maker_c< &A::bar >::ptr() ;
// call wrapper
const auto bar_wrapped = std::function< int( const A*, short, char, char ) >( &A::bar ) ;
A a ;
pfn_foo( &a, 1, 'a' ) ; // A::foo(int,char)
foo_wrapped( &a, 1, 'a' ) ; // A::foo(int,char)
const A ca ;
pfn_bar( &ca, 2, 'b', 'c' ) ; // A::bar(short,char,char) const
bar_wrapped( &ca, 2, 'b', 'c' ) ; // A::bar(short,char,char) const
}
|