Question: I want to have a class that creates different sorts of objects based on a string I pass it. From my research, this best describes the Factory design pattern. I am having success implementing it, but I've run into a design issue: I don't know how to create objects with different length constructors.

Let's take for example, an abstract parent class called Pet. From it are 3 children: Fish, Cat, and Dog. They all inherit weight and color from Pet, so that goes in their constructors. But a fish might want a number of fins and a boolean regarding whether it is a saltwater fish. That's a 4 parameter constructor. Cat would like number of legs. That's 3 parameters. The dog might have parameters for legs, breed, and whether he plays well with other dogs, for 5 parameters.

In C++, I understand that there isn't any reflection, so the most common practice seems to be to just declare a map of string to function pointers, where the function pointer points to a function that looks something like this:

```
    template<typename T> Pet* createObject(int weight, std::string color) {return new T(weight, color);}

```

Again, I'm not sure how I would stuff more parameters into the call without affecting the calls of other objects' constructors.

I can think of two workarounds: make new functions to accept different amount of parameters or make default parameters for constructors above a certain size.

Workaround 1 seems kind of excessive depending on how many different parameter sizes I have.

Workaround 2 seems to disregard the entire point of a constructor, as I will be forced to assign data after calling the constructor.

Are there any other better workarounds?

Answer: 
Well that was fun ! I've resorted to using factory sub-functions which parse the stream for arguments themselves. I've added in a Registrar pattern for simplicity of use, and of course a good dose of TMP.

Here is the abridged code :

```
/* Pet and derived classes omitted */
/*    Registrar pattern omitted    */

struct PetFactory {
    using PetCtr = std::unique_ptr<Pet> (*)(std::istream &);

    static auto make(std::istream &stream) {
        std::string str;
        stream >> str;
        return ctrMap().at(str)(stream);
    }

    using PetCtrMap = std::map<std::string, PetCtr>;
    static PetCtrMap &ctrMap();
};

template <class T, class... Args, std::size_t... Idx>
auto streamCtr_(std::istream &stream, std::index_sequence<Idx...> const &) {

    std::tuple<Args...> args;

    using unpack = int[];
    unpack{0, (void(stream >> std::get<Idx>(args)), 0)...};

    return std::make_unique<T>(std::move(std::get<Idx>(args))...);
}

template <class T, class... Args>
auto streamCtr(std::istream &stream) {
    return std::unique_ptr<Pet>(streamCtr_<T, Args...>(
        stream,
        std::index_sequence_for<Args...>{}
    ));
}

int main() {
    PetFactory::make("fish 1 silver 5 true");
    PetFactory::make("cat 4 tabby 9");
    PetFactory::make("dog 17 white husky playful");
}

```

**Output:**

```
I'm a 1kg silver fish with 5 fins, living in salty water.
I'm a 4kg tabby cat with 9 lives.
I'm a 17kg white husky and I'm playful.

```

The full commented code is available [here on Coliru](http://coliru.stacked-crooked.com/a/5aa3660047381336). Thanks for the challenge !
There are many approaches to this problem; the one I prefer may not be the most elegant, but it is extremely explicit. Basically, you create a map to `boost::any` pointers, and all constructors now simply take such a map.

```
using MyArgs = unordered_map<string, boost::any>;

class Fish {
  Fish(MyArgs args) {
    int num_fins = boost::any_cast<int>(args.at("num_fins"));
  }

```

Now all of your constructors have the same signature, so your factory can just look this like:

```
unique_ptr<Pet> factory(string animal_name, MyArgs args) {
  auto func = factory_map.at(animal_name);
  return func(args);
}

```

Edit: I should also note that if you make a mistake, that is your MyArgs is missing an argument or has one of the wrong type, an exception will be thrown. So you can get a nice clear error and even handle it, as opposed to getting UB.