#include <iostream>
#include <tuple>
#include <cassert>
 
struct foo 
{
	foo() = delete;
 
	foo(int i, int k)
	: i(i), k(k){}
 
	void operator()()
	{ std::cout << i << " " << k << std::endl;}
 
	int i;
	int k;
};
 
struct bar
{
	bar() = delete;
 
	bar(int x)
	: x(x){}
 
	void operator()()
	{ std::cout << x << std::endl;}
 
	int x;
};
 
 
template <size_t I>
struct visit_impl
{
    template <typename T, typename F>
    static void visit(T& tup, size_t idx, F fun)
    {
        if (idx == I - 1) fun(std::get<I - 1>(tup));
        else visit_impl<I - 1>::visit(tup, idx, fun);
    }
};
 
template <>
struct visit_impl<0>
{
    template <typename T, typename F>
    static void visit(T& tup, size_t idx, F fun) { assert(false); }
};
 
/// visit at runtime the tuple item at idx and run F
template <typename F, typename... Ts>
void visit_at(std::tuple<Ts...> const& tup, size_t idx, F fun)
{
    visit_impl<sizeof...(Ts)>::visit(tup, idx, fun);
}
 
/// visit at runtime the tuple item at idx and run F
template <typename F, typename... Ts>
void visit_at(std::tuple<Ts...>& tup, size_t idx, F fun)
{
    visit_impl<sizeof...(Ts)>::visit(tup, idx, fun);
}
 
/// make an object
template <typename T, typename... Args>
T make_class(Args ...args)
{
	return T(args...);
}
 
template <typename... Args>
void make_classes(Args... args)
{
	auto t = std::tuple<Args...>(args...);
	unsigned int size = std::tuple_size<decltype(t)>::value;
	auto execute = [](auto & obj){ obj.operator()(); };
 
	for (int i = 0; i < size; i++) {
		visit_at(t, i, execute);
	}
}
 
int main() 
{
	make_classes(
				 foo(2, 6),
				 bar(3),
				 foo(10,11),
				 bar(9)
			   );
}
 
				I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDxjYXNzZXJ0PgoKc3RydWN0IGZvbyAKewoJZm9vKCkgPSBkZWxldGU7CgkKCWZvbyhpbnQgaSwgaW50IGspCgk6IGkoaSksIGsoayl7fQoJCgl2b2lkIG9wZXJhdG9yKCkoKQoJeyBzdGQ6OmNvdXQgPDwgaSA8PCAiICIgPDwgayA8PCBzdGQ6OmVuZGw7fQoJCglpbnQgaTsKCWludCBrOwp9OwoKc3RydWN0IGJhcgp7CgliYXIoKSA9IGRlbGV0ZTsKCQoJYmFyKGludCB4KQoJOiB4KHgpe30KCQoJdm9pZCBvcGVyYXRvcigpKCkKCXsgc3RkOjpjb3V0IDw8IHggPDwgc3RkOjplbmRsO30KCQoJaW50IHg7Cn07CgoKdGVtcGxhdGUgPHNpemVfdCBJPgpzdHJ1Y3QgdmlzaXRfaW1wbAp7CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRj4KICAgIHN0YXRpYyB2b2lkIHZpc2l0KFQmIHR1cCwgc2l6ZV90IGlkeCwgRiBmdW4pCiAgICB7CiAgICAgICAgaWYgKGlkeCA9PSBJIC0gMSkgZnVuKHN0ZDo6Z2V0PEkgLSAxPih0dXApKTsKICAgICAgICBlbHNlIHZpc2l0X2ltcGw8SSAtIDE+Ojp2aXNpdCh0dXAsIGlkeCwgZnVuKTsKICAgIH0KfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCB2aXNpdF9pbXBsPDA+CnsKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBGPgogICAgc3RhdGljIHZvaWQgdmlzaXQoVCYgdHVwLCBzaXplX3QgaWR4LCBGIGZ1bikgeyBhc3NlcnQoZmFsc2UpOyB9Cn07CiAKLy8vIHZpc2l0IGF0IHJ1bnRpbWUgdGhlIHR1cGxlIGl0ZW0gYXQgaWR4IGFuZCBydW4gRgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRiwgdHlwZW5hbWUuLi4gVHM+CnZvaWQgdmlzaXRfYXQoc3RkOjp0dXBsZTxUcy4uLj4gY29uc3QmIHR1cCwgc2l6ZV90IGlkeCwgRiBmdW4pCnsKICAgIHZpc2l0X2ltcGw8c2l6ZW9mLi4uKFRzKT46OnZpc2l0KHR1cCwgaWR4LCBmdW4pOwp9CgovLy8gdmlzaXQgYXQgcnVudGltZSB0aGUgdHVwbGUgaXRlbSBhdCBpZHggYW5kIHJ1biBGCnRlbXBsYXRlIDx0eXBlbmFtZSBGLCB0eXBlbmFtZS4uLiBUcz4Kdm9pZCB2aXNpdF9hdChzdGQ6OnR1cGxlPFRzLi4uPiYgdHVwLCBzaXplX3QgaWR4LCBGIGZ1bikKewogICAgdmlzaXRfaW1wbDxzaXplb2YuLi4oVHMpPjo6dmlzaXQodHVwLCBpZHgsIGZ1bik7Cn0KCi8vLyBtYWtlIGFuIG9iamVjdAp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi4gQXJncz4KVCBtYWtlX2NsYXNzKEFyZ3MgLi4uYXJncykKewoJcmV0dXJuIFQoYXJncy4uLik7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBBcmdzPgp2b2lkIG1ha2VfY2xhc3NlcyhBcmdzLi4uIGFyZ3MpCnsKCWF1dG8gdCA9IHN0ZDo6dHVwbGU8QXJncy4uLj4oYXJncy4uLik7Cgl1bnNpZ25lZCBpbnQgc2l6ZSA9IHN0ZDo6dHVwbGVfc2l6ZTxkZWNsdHlwZSh0KT46OnZhbHVlOwoJYXV0byBleGVjdXRlID0gW10oYXV0byAmIG9iail7IG9iai5vcGVyYXRvcigpKCk7IH07CgkKCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJdmlzaXRfYXQodCwgaSwgZXhlY3V0ZSk7Cgl9Cn0KCmludCBtYWluKCkgCnsKCW1ha2VfY2xhc3NlcygKCQkJCSBmb28oMiwgNiksCgkJCQkgYmFyKDMpLAoJCQkJIGZvbygxMCwxMSksCgkJCQkgYmFyKDkpCgkJCSAgICk7Cn0K