0

I am looking to create an object that can instantiate a class on command. The reason why I want to do it like this, is because I have to create instances of an object, that all have the same initial parameters read from a file, but I want to load those parameters only once. My solution is using lambdas, but it feels very dirty:

#include <functional>

template <class GENERATED_TYPE, class... Args> requires requires(Args... data) {
    { new GENERATED_TYPE(data...) } -> std::same_as<GENERATED_TYPE*>;
}
class ObjectGenerator {
    public:
        ObjectGenerator(Args... data){ instance_generator = [data...](){ return new GENERATED_TYPE(data...); }; }
        ~ObjectGenerator(){}
        GENERATED_TYPE* getInstance() { return instance_generator(); }
    private:
        std::function<GENERATED_TYPE*()> instance_generator;
};

Is there a better way, by storing Args... data somehow, and then using the stored parameter pack later on?

Lala5th
  • 1,137
  • 7
  • 18
  • @NathanOliver, I believe `ObjectGenerator` is already a template... – r3mus n0x Jul 01 '21 at 19:33
  • @r3musn0x Oh yeah. I though the OP was creating a concept, not that it was the constraints on the parameters. Still need to adjust to concepts and constraints. At least now I can add an answer :) – NathanOliver Jul 01 '21 at 19:38

1 Answers1

2

Is there a better way, by storing Args... data somehow, and then using the stored parameter pack later on?

Not sure about better, but you can store the arguments in a std::tuple and then use std::make_from_tuple to construct the object each time. That would look like

#include <functional>
#include <tuple>

template <class GENERATED_TYPE, class... Args> requires requires(Args... data) {
    { new GENERATED_TYPE(data...) } -> std::same_as<GENERATED_TYPE*>;
}
class ObjectGenerator {
    public:
        ObjectGenerator(Args... data) : arguments(std::move(data)...) {}
        
        GENERATED_TYPE getInstance() { 
            return std::make_from_tuple<GENERATED_TYPE>(arguments); 
        }
    private:
        std::tuple<Args...> arguments;
};
NathanOliver
  • 171,901
  • 28
  • 288
  • 402