#include <type_traits>
#include <iostream>


template <typename T, typename M, typename ...Args>
auto invoke( T *object, M method, Args&&... args ) -> decltype( *method )
{
    return ( static_cast<T*>( object )->*method )( std::forward<Args>( args )... );
}

struct Foo
{
    int triple( int val )
    {
        return val * 3;
    }
};

int main()
{
    Foo foo;

    std::cout << invoke( &foo, &Foo::triple, 5 );   // output: 15

    return 0;
}
