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");
}

基本的にObjectMaker、コンストラクターに渡される引数をクラスに保存し、呼び出されFooたときにそれらを使用するようにします。ObjectMaker::create()私が理解できないのは、tupleから のコンストラクターへの値を取得する方法Fooです。

4

1 に答える 1

1

@Xeo によってリンクされた一致する関数ポインターを呼び出すために、タプルの「アンパック」でレイアウトされたコードと概念を恥知らずに適用しました。私が理解している基本的な考え方は、一連のインデックスをタプルに作成し、それらを std::get への呼び出しにアンパックすることです。以下のコードは g++ 4.5.2 で動作します。私は通常 msvc10 で動作するため、この種の楽しみはまだ利用できません - クールなものです!

#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");
}
于 2012-07-01T05:24:46.590 に答える