#include <iostream>
#include <functional>
#include <vector>
#include <memory>
#include <random>
struct Base
{
virtual void print() const = 0;
virtual ~Base() {}
};
struct D1 : public Base { void print() const { std::cout << "D1\n"; } };
struct D2 : public Base { void print() const { std::cout << "D2\n"; } };
struct D3 : public Base { void print() const { std::cout << "D3\n"; } };
struct D4 : public Base { void print() const { std::cout << "D4\n"; } };
struct D5 : public Base { void print() const { std::cout << "D5\n"; } };
template <typename T>
T* new_class()
{
return new T;
}
typedef std::function<Base*()> creationFunction;
enum class_type { eD1, eD2, eD3, eD4, eD5 };
creationFunction create [] =
{
new_class<D1>,
new_class<D2>,
new_class<D3>,
new_class<D4>,
new_class<D5>
};
Base* getClass(class_type type)
{
return create[type]();
}
int main()
{
std::mt19937 engine( (std::random_device())() );
std::uniform_int_distribution<unsigned> ct(eD1, eD5);
auto rand_class = [&]() { return static_cast<class_type>(ct(engine)); };
std::vector<std::unique_ptr<Base>> container;
for (unsigned i = 0; i < 20; ++i)
container.emplace_back(getClass(rand_class()));
for (auto & element : container)
element->print();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPHJhbmRvbT4KCnN0cnVjdCBCYXNlCnsKICAgIHZpcnR1YWwgdm9pZCBwcmludCgpIGNvbnN0ID0gMDsKICAgIHZpcnR1YWwgfkJhc2UoKSB7fQp9OwoKCnN0cnVjdCBEMSA6IHB1YmxpYyBCYXNlIHsgdm9pZCBwcmludCgpIGNvbnN0IHsgc3RkOjpjb3V0IDw8ICJEMVxuIjsgfSB9OwpzdHJ1Y3QgRDIgOiBwdWJsaWMgQmFzZSB7IHZvaWQgcHJpbnQoKSBjb25zdCB7IHN0ZDo6Y291dCA8PCAiRDJcbiI7IH0gfTsKc3RydWN0IEQzIDogcHVibGljIEJhc2UgeyB2b2lkIHByaW50KCkgY29uc3QgeyBzdGQ6OmNvdXQgPDwgIkQzXG4iOyB9IH07CnN0cnVjdCBENCA6IHB1YmxpYyBCYXNlIHsgdm9pZCBwcmludCgpIGNvbnN0IHsgc3RkOjpjb3V0IDw8ICJENFxuIjsgfSB9OwpzdHJ1Y3QgRDUgOiBwdWJsaWMgQmFzZSB7IHZvaWQgcHJpbnQoKSBjb25zdCB7IHN0ZDo6Y291dCA8PCAiRDVcbiI7IH0gfTsKCgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KVCogbmV3X2NsYXNzKCkKewogICAgcmV0dXJuIG5ldyBUOwp9Cgp0eXBlZGVmIHN0ZDo6ZnVuY3Rpb248QmFzZSooKT4gY3JlYXRpb25GdW5jdGlvbjsKCmVudW0gY2xhc3NfdHlwZSB7IGVEMSwgZUQyLCBlRDMsIGVENCwgZUQ1IH07CgpjcmVhdGlvbkZ1bmN0aW9uIGNyZWF0ZSBbXSA9CnsKICAgIG5ld19jbGFzczxEMT4sCiAgICBuZXdfY2xhc3M8RDI+LAogICAgbmV3X2NsYXNzPEQzPiwKICAgIG5ld19jbGFzczxEND4sCiAgICBuZXdfY2xhc3M8RDU+Cn07CgpCYXNlKiBnZXRDbGFzcyhjbGFzc190eXBlIHR5cGUpCnsKICAgIHJldHVybiBjcmVhdGVbdHlwZV0oKTsKfQoKaW50IG1haW4oKQp7CiAgICBzdGQ6Om10MTk5MzcgZW5naW5lKCAoc3RkOjpyYW5kb21fZGV2aWNlKCkpKCkgKTsKICAgIHN0ZDo6dW5pZm9ybV9pbnRfZGlzdHJpYnV0aW9uPHVuc2lnbmVkPiBjdChlRDEsIGVENSk7CgogICAgYXV0byByYW5kX2NsYXNzID0gWyZdKCkgeyByZXR1cm4gc3RhdGljX2Nhc3Q8Y2xhc3NfdHlwZT4oY3QoZW5naW5lKSk7IH07CgogICAgc3RkOjp2ZWN0b3I8c3RkOjp1bmlxdWVfcHRyPEJhc2U+PiBjb250YWluZXI7CiAgICBmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgMjA7ICsraSkKICAgICAgICBjb250YWluZXIuZW1wbGFjZV9iYWNrKGdldENsYXNzKHJhbmRfY2xhc3MoKSkpOwoKICAgIGZvciAoYXV0byAmIGVsZW1lbnQgOiBjb250YWluZXIpCiAgICAgICAgZWxlbWVudC0+cHJpbnQoKTsKfQ==