3
#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?

Xeo
  • 129,499
  • 52
  • 291
  • 397
Mark
  • 2,082
  • 3
  • 17
  • 30
  • 1
    You might take a look at [this question](http://stackoverflow.com/a/4121942/246886). – Jon Purdy Jul 01 '12 at 02:07
  • 1
    possible duplicate of ["unpacking" a tuple to call a matching function pointer](http://stackoverflow.com/questions/7858817/unpacking-a-tuple-to-call-a-matching-function-pointer) – Xeo Jul 01 '12 at 02:16
  • 2
    Btw, please don't use the HTML tags for code markup, use backticks for inline and four leading spaces (or mark and ctrl-K) for a block of code. – Xeo Jul 01 '12 at 02:16

1 Answers1

1

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");
}
Community
  • 1
  • 1
Zac
  • 3,235
  • 4
  • 25
  • 30