// A simple example using type-erasure.
#include <iostream>
#include <vector>
#include <memory>
class Example {
struct _Concept {
virtual ~_Concept() = default;
virtual const char* f() const = 0;
};
template<typename T>
struct _Model : _Concept {
_Model(T* p)
: m_p(p)
{}
const char* f() const
{ return m_p->f(); }
private:
T* m_p;
};
std::vector<std::unique_ptr<_Concept>> m_items;
public:
template<typename T>
void add_item(T* p)
{
m_items.push_back(std::make_unique<_Model<T>>(p));
}
void process_items()
{
for (const auto& x : m_items)
std::cout << x->f() << std::endl;
}
};
// Use.
struct A {
const char* f()
{ return "A::f"; }
};
struct B {
const char* f()
{ return "B::f"; }
};
int main()
{
Example x;
A a;
B b;
x.add_item(&a);
x.add_item(&b);
x.process_items();
}
Ly8gQSBzaW1wbGUgZXhhbXBsZSB1c2luZyB0eXBlLWVyYXN1cmUuCgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxtZW1vcnk+CgpjbGFzcyBFeGFtcGxlIHsKICAgIHN0cnVjdCBfQ29uY2VwdCB7CiAgICAgICAgdmlydHVhbCB+X0NvbmNlcHQoKSA9IGRlZmF1bHQ7CiAgICAgICAgdmlydHVhbCBjb25zdCBjaGFyKiBmKCkgY29uc3QgPSAwOwogICAgfTsKCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgogICAgc3RydWN0IF9Nb2RlbCA6IF9Db25jZXB0IHsKICAgICAgICBfTW9kZWwoVCogcCkKICAgICAgICA6IG1fcChwKQogICAgICAgIHt9CiAgICAgICAgY29uc3QgY2hhciogZigpIGNvbnN0CiAgICAgICAgeyByZXR1cm4gbV9wLT5mKCk7IH0KICAgIHByaXZhdGU6CiAgICAgICAgVCogbV9wOwogICAgfTsKCiAgICBzdGQ6OnZlY3RvcjxzdGQ6OnVuaXF1ZV9wdHI8X0NvbmNlcHQ+PiBtX2l0ZW1zOwoKcHVibGljOgogICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICAgIHZvaWQgYWRkX2l0ZW0oVCogcCkKICAgIHsKICAgICAgICBtX2l0ZW1zLnB1c2hfYmFjayhzdGQ6Om1ha2VfdW5pcXVlPF9Nb2RlbDxUPj4ocCkpOwogICAgfQoKICAgIHZvaWQgcHJvY2Vzc19pdGVtcygpCiAgICB7CiAgICAgICAgZm9yIChjb25zdCBhdXRvJiB4IDogbV9pdGVtcykKICAgICAgICAgICAgc3RkOjpjb3V0IDw8IHgtPmYoKSA8PCBzdGQ6OmVuZGw7CiAgICB9Cn07CgovLyBVc2UuCgpzdHJ1Y3QgQSB7CiAgICBjb25zdCBjaGFyKiBmKCkKICAgIHsgcmV0dXJuICJBOjpmIjsgfQp9OwoKc3RydWN0IEIgewogICAgY29uc3QgY2hhciogZigpCiAgICB7IHJldHVybiAiQjo6ZiI7IH0KfTsKCmludCBtYWluKCkKewogICAgRXhhbXBsZSB4OwogICAgQSBhOwogICAgQiBiOwogICAgeC5hZGRfaXRlbSgmYSk7CiAgICB4LmFkZF9pdGVtKCZiKTsKICAgIHgucHJvY2Vzc19pdGVtcygpOwp9