#include <iostream>
#include <functional>

template <typename func_t, func_t func>
struct Foo {
    template <typename... Arguments>
	void execute(Arguments... args) {
		func(args ...);
	}
};

template <typename T, typename func_t, func_t func>
struct FooMember {
	T member;

	FooMember(T member) : member(member) {}

	template <typename... Arguments>
	void execute(Arguments... args) {
		std::function<void(T&, Arguments ...)> f(func);
		f(this->member, args ...);
	}
};

/////////////////////////////////////////////

struct Bar {
	int z;

	Bar(int z) : z(z) {}
	void add(int x, int y) { std::cout << x + y + z << std::endl; }
};

void padd(int x, int y, int z) { std::cout << x + y + z << std::endl; }

int main() {
	auto a = Foo<decltype(&padd), &padd>();
	auto b = FooMember<Bar, decltype(&Bar::add), &Bar::add>(Bar(2));

	a.execute(4, 5, 6); // prints 4+5+6 : 15
	b.execute(4, 5); // prints 4+5+a.z : 4+5+2 : 11

	return 0;
}
