#include <iostream>
#include <string>
template< typename T >
class Invoker
{
public:
Invoker() = default;
virtual ~Invoker() = default;
public:
template <typename R, typename ... Args1, typename ... Args2>
static R invoke( T* object, R( T::* method )( Args1... ), Args2&&... args );
};
template <typename T>
template <typename R, typename ... Args1, typename ... Args2>
R Invoker<T>::invoke(T* object, R( T::* method)(Args1...), Args2&&... args)
{
return ( object->*method )( std::forward<Args1>( args )... );
}
struct Foo
{
int bar( const std::string& txt )
{
return 42;
}
};
int main()
{
Foo foo;
auto result = Invoker<Foo>::invoke( &foo, &Foo::bar, std::string() );
std::cout << result; // 42
return 0;
}
CSNpbmNsdWRlIDxpb3N0cmVhbT4KCSNpbmNsdWRlIDxzdHJpbmc+CgogICAgdGVtcGxhdGU8IHR5cGVuYW1lIFQgPgogICAgY2xhc3MgSW52b2tlcgogICAgewogICAgcHVibGljOgogICAgICAgIEludm9rZXIoKSA9IGRlZmF1bHQ7CiAgICAgICAgdmlydHVhbCB+SW52b2tlcigpID0gZGVmYXVsdDsKCiAgICBwdWJsaWM6CiAgICAgICAgdGVtcGxhdGUgPHR5cGVuYW1lIFIsIHR5cGVuYW1lIC4uLiBBcmdzMSwgdHlwZW5hbWUgLi4uIEFyZ3MyPgogICAgICAgIHN0YXRpYyBSIGludm9rZSggVCogb2JqZWN0LCBSKCBUOjoqIG1ldGhvZCApKCBBcmdzMS4uLiApLCBBcmdzMiYmLi4uIGFyZ3MgKTsKICAgIH07CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgUiwgdHlwZW5hbWUgLi4uIEFyZ3MxLCB0eXBlbmFtZSAuLi4gQXJnczI+CiAgICBSIEludm9rZXI8VD46Omludm9rZShUKiBvYmplY3QsIFIoIFQ6OiogbWV0aG9kKShBcmdzMS4uLiksIEFyZ3MyJiYuLi4gYXJncykKICAgIHsKICAgICAgICByZXR1cm4gKCBvYmplY3QtPiptZXRob2QgKSggc3RkOjpmb3J3YXJkPEFyZ3MxPiggYXJncyApLi4uICk7CiAgICB9CgogICAgCiAgICBzdHJ1Y3QgRm9vCiAgICB7CiAgICAJaW50IGJhciggY29uc3Qgc3RkOjpzdHJpbmcmIHR4dCApCiAgICAJewogICAgCQlyZXR1cm4gNDI7CiAgICAJfQogICAgfTsKICAgIAogICAgaW50IG1haW4oKQogICAgewogICAgCUZvbyBmb287CiAgICAJCiAgICAJYXV0byByZXN1bHQgPSBJbnZva2VyPEZvbz46Omludm9rZSggJmZvbywgJkZvbzo6YmFyLCBzdGQ6OnN0cmluZygpICk7CiAgICAJc3RkOjpjb3V0IDw8IHJlc3VsdDsJLy8gNDIKICAgIAkKICAgIAlyZXR1cm4gMDsKICAgIH0=