Reputation: 2112
#include <tuple>
class Foo {
public:
Foo(int i, double d, const char* str) { }
};
template<class T, class... CtorArgTypes>
class ObjectMaker {
public:
ObjectMaker(CtorArgTypes... ctorArgs) : m_ctorArgs(ctorArgs...)
{
}
Foo* create()
{
//What do I do here?
}
private:
std::tuple<CtorArgTypes...> m_ctorArgs;
};
int main(int, char**)
{
ObjectMaker<Foo, int, double, const char*> fooMaker(42, 5.3, "Hello");
Foo* myFoo = fooMaker.create(); //this should do new Foo(42, 5.3, "Hello");
}
Basically, I want the class ObjectMaker
to save the arguments that will be passed to the constructor of Foo
and use them when ObjectMaker::create()
is called. What I can't figure out is how to I get the values from the tuple
to the constructor of Foo
?
Upvotes: 3
Views: 2457
Reputation: 3285
Shamelessly applied the code & concepts laid out in "unpacking" a tuple to call a matching function pointer linked by @Xeo. Basic idea as I understand it is to create a sequence of indexes into your tuple and unpack them into calls to std::get. Code below works on g++ 4.5.2, I typically work with msvc10 so this sort of fun isn't available yet - cool stuff!
#include <tuple>
#include <iostream>
class Foo {
public:
Foo(int i, double d, const char* str)
{
std::cout << "Foo constructor: i=" << i << " d=" << d << "str=" << str << std::endl;
}
};
template<int ...>
struct seq { };
template<int N, int ...S>
struct gens : gens<N-1, N-1, S...> { };
template<int ...S>
struct gens<0, S...> {
typedef seq<S...> type;
};
template<class T, class... CtorArgTypes>
class ObjectMaker {
public:
ObjectMaker(CtorArgTypes... ctorArgs) : m_ctorArgs(ctorArgs...)
{
}
Foo* create()
{
return create_T( typename gens<sizeof ...(CtorArgTypes)>::type() );
}
private:
template< int ...S >
T* create_T( seq<S...>)
{
return new T(std::get<S>(m_ctorArgs) ...);
}
std::tuple<CtorArgTypes...> m_ctorArgs;
};
int main(int, char**)
{
ObjectMaker<Foo, int, double, const char*> fooMaker(42, 5.3, "Hello");
Foo* myFoo = fooMaker.create(); //this should do new Foo(42, 5.3, "Hello");
}
Upvotes: 1