#include <iostream>

struct Extension
{
	void f(){std::cout<<"f"<<std::endl;}
	float g(int x, float y, int z)
	{
		std::cout << "x = " << x << std::endl
		          << "y = " << y << std::endl
		          << "z = " << z << std::endl;
		return 4.5f;
	}
};

template<typename R, typename... Args>
R CallExtMF(Extension &ext, void *f, Args... args)
{
	R (Extension::*mfp)(Args...) = *reinterpret_cast<R (Extension::**)(Args...)>(&f);
	return (ext.*mfp)(args...);
}

int main()
{
	void *f = reinterpret_cast<void *>(&Extension::f);
	void *g = reinterpret_cast<void *>(&Extension::g);
	
	Extension e;
	
	CallExtMF<void>(e, f);
	float p = 2.5f;
	float rv = CallExtMF<float>(e, g, 1, *reinterpret_cast<int *>(&p), 3);
	std::cout << "rv = " << rv << std::endl;
}
