#include <memory>
#include <vector>
#include <iostream>
struct some_interface
{
virtual ~some_interface()
{}
virtual void foo() = 0;
};
template <typename Foo>
struct C : public some_interface
{
std::unique_ptr<Foo> foo_;
C(std::unique_ptr<Foo> foo_)
: foo_(std::move(foo_))
{}
virtual void foo()
{
foo_->foo();
}
};
struct known_foo
{
void foo()
{
std::cout << "known foo\n";
}
};
struct foo_base
{
virtual ~foo_base()
{}
virtual void foo() = 0;
};
struct unknown_foo : public foo_base
{
virtual void foo()
{
std::cout << "unknown foo\n";
}
};
template <typename T, typename... Args>
std::unique_ptr<T> bad_make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
int main()
{
std::vector<std::unique_ptr<some_interface>> interfaces;
interfaces.push_back(bad_make_unique<C<known_foo>>(bad_make_unique<known_foo>()));
interfaces.push_back(bad_make_unique<C<foo_base>>(bad_make_unique<unknown_foo>()));
for (auto& e : interfaces)
e->foo();
}
I2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKc3RydWN0IHNvbWVfaW50ZXJmYWNlCnsKICAgIHZpcnR1YWwgfnNvbWVfaW50ZXJmYWNlKCkKICAgIHt9CiAgICAKICAgIHZpcnR1YWwgdm9pZCBmb28oKSA9IDA7Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRm9vPgpzdHJ1Y3QgQyA6IHB1YmxpYyBzb21lX2ludGVyZmFjZQp7CiAgICBzdGQ6OnVuaXF1ZV9wdHI8Rm9vPiBmb29fOwogICAgCiAgICBDKHN0ZDo6dW5pcXVlX3B0cjxGb28+IGZvb18pCiAgICAgICAgOiBmb29fKHN0ZDo6bW92ZShmb29fKSkKICAgIHt9CiAgICAKICAgIHZpcnR1YWwgdm9pZCBmb28oKQogICAgewogICAgICAgIGZvb18tPmZvbygpOwogICAgfQp9OwoKc3RydWN0IGtub3duX2Zvbwp7CiAgICB2b2lkIGZvbygpCiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8ICJrbm93biBmb29cbiI7CiAgICB9Cn07CgpzdHJ1Y3QgZm9vX2Jhc2UKewogICAgdmlydHVhbCB+Zm9vX2Jhc2UoKQogICAge30KICAgIAogICAgdmlydHVhbCB2b2lkIGZvbygpID0gMDsKfTsKCnN0cnVjdCB1bmtub3duX2ZvbyA6IHB1YmxpYyBmb29fYmFzZQp7CiAgICB2aXJ0dWFsIHZvaWQgZm9vKCkKICAgIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgInVua25vd24gZm9vXG4iOwogICAgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIEFyZ3M+CnN0ZDo6dW5pcXVlX3B0cjxUPiBiYWRfbWFrZV91bmlxdWUoQXJncyYmLi4uIGFyZ3MpCnsKICAgIHJldHVybiBzdGQ6OnVuaXF1ZV9wdHI8VD4obmV3IFQoc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uKSk7Cn0KCmludCBtYWluKCkKewogICAgc3RkOjp2ZWN0b3I8c3RkOjp1bmlxdWVfcHRyPHNvbWVfaW50ZXJmYWNlPj4gaW50ZXJmYWNlczsKICAgIGludGVyZmFjZXMucHVzaF9iYWNrKGJhZF9tYWtlX3VuaXF1ZTxDPGtub3duX2Zvbz4+KGJhZF9tYWtlX3VuaXF1ZTxrbm93bl9mb28+KCkpKTsKICAgIGludGVyZmFjZXMucHVzaF9iYWNrKGJhZF9tYWtlX3VuaXF1ZTxDPGZvb19iYXNlPj4oYmFkX21ha2VfdW5pcXVlPHVua25vd25fZm9vPigpKSk7CiAgICAKICAgIGZvciAoYXV0byYgZSA6IGludGVyZmFjZXMpCiAgICAgICAgZS0+Zm9vKCk7Cn0=