invoking function for each variadic template arguments and passing the result as constructor arguments

142 views Asked by At

So i want to generate a lambda that will invoke a constructor by retrieving the constructor's parameters from a factory.

I want to convert this code that works right now into a variadic template so it will work with any number of constructor parameters.

Any idea how to do this?

template <class Class>
struct Constructor
{
};


template <class Class>
struct Constructor< Class() >{
    static std::function<Class*()> Instanciator(Factory& factory)
    {
        return []{
            return new Class();
        };
    }
};

template <class Class, class Arg1>
struct Constructor< Class(Arg1) >{
    static std::function<Class*()> Instanciator(Factory& factory)
    {
        return []{
            return new Class(factory.Get<Arg1>());
        };
    }
};

template <class Class, class Arg1, class Arg2>
struct Constructor< Class(Arg1, Arg2) >{
    static std::function<Class*()> Instanciator(Factory& factory)
    {
        return []{
            return new Class(factory.Get<Arg1>(), factory.Get<Arg2>());
        };
    }
};
1

There are 1 answers

1
Yakk - Adam Nevraumont On BEST ANSWER
template <class Class>
struct Constructor
{};

template <class Class, class...Args>
struct Constructor< Class(Args...) > {
  template<class Factory>
  std::function<Class*()> operator()(Factory& factory)const
  {
    return []{
      return new Class(factory.Get<Args>()...);
    };
  }
};

now Constructor< Foo(Args...) > is a function object of type Factory -> std::function<Foo*()>, where Factory supports .Get<Args>() for each Args.

Me, I'd also want to include the index in the .Get<?>() call, in case your class takes two int arguments or whatever.

I removed Instanciator and the static bit, because a class whose only purpose is to produce constructors doesn't need that noise. Making it an invokable stateless function object is more idiomatic.