#include <iostream>
#include <vector>
template <class T>
struct holder {
std::vector<T> data;
};
struct gameboy;
struct ball { ball(gameboy *) {} };
struct door { door(gameboy *) {} };
struct piss { piss(gameboy *) {} };
struct foo {};
struct gameboy
: private holder<ball>
, private holder<door>
, private holder<piss>
{
template <class T>
T & push_back()
{
holder<T> & ancestor = static_cast<holder<T> &>(*this); // compile error here if type mismatch
ancestor.data.push_back(T(this));
return *ancestor.data.rbegin();
}
template <class T>
typename std::vector<T>::size_type size() const
{
return holder<T>::data.size(); // or you can just ask your ancestor directly
}
};
int main()
{
gameboy boy;
boy.push_back<ball>();
boy.push_back<door>();
boy.push_back<piss>();
boy.push_back<door>();
std::cout << boy.size<door>() << std::endl;
// std::cout << boy.size<foo>() << std::endl; // cannot use foo!
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgoKdGVtcGxhdGUgPGNsYXNzIFQ+CnN0cnVjdCBob2xkZXIgewogICAgc3RkOjp2ZWN0b3I8VD4JZGF0YTsKfTsKCnN0cnVjdCBnYW1lYm95OwoKc3RydWN0IGJhbGwgeyBiYWxsKGdhbWVib3kgKikge30gfTsKc3RydWN0IGRvb3IgeyBkb29yKGdhbWVib3kgKikge30gfTsKc3RydWN0IHBpc3MgeyBwaXNzKGdhbWVib3kgKikge30gfTsKc3RydWN0IGZvbyB7fTsKCnN0cnVjdCBnYW1lYm95Cgk6IHByaXZhdGUgaG9sZGVyPGJhbGw+CgksIHByaXZhdGUgaG9sZGVyPGRvb3I+CgksIHByaXZhdGUgaG9sZGVyPHBpc3M+CnsKCXRlbXBsYXRlIDxjbGFzcyBUPgoJVCAmIHB1c2hfYmFjaygpCgl7CgkJaG9sZGVyPFQ+ICYgYW5jZXN0b3IgPSBzdGF0aWNfY2FzdDxob2xkZXI8VD4gJj4oKnRoaXMpOwkvLyBjb21waWxlIGVycm9yIGhlcmUgaWYgdHlwZSBtaXNtYXRjaAoJCWFuY2VzdG9yLmRhdGEucHVzaF9iYWNrKFQodGhpcykpOwoJCXJldHVybiAqYW5jZXN0b3IuZGF0YS5yYmVnaW4oKTsKCX0KCgl0ZW1wbGF0ZSA8Y2xhc3MgVD4KCXR5cGVuYW1lIHN0ZDo6dmVjdG9yPFQ+OjpzaXplX3R5cGUgc2l6ZSgpIGNvbnN0IAoJewoJCXJldHVybiBob2xkZXI8VD46OmRhdGEuc2l6ZSgpOyAvLyBvciB5b3UgY2FuIGp1c3QgYXNrIHlvdXIgYW5jZXN0b3IgZGlyZWN0bHkKCX0KfTsKCmludCBtYWluKCkKewoJZ2FtZWJveSBib3k7Cglib3kucHVzaF9iYWNrPGJhbGw+KCk7Cglib3kucHVzaF9iYWNrPGRvb3I+KCk7Cglib3kucHVzaF9iYWNrPHBpc3M+KCk7Cglib3kucHVzaF9iYWNrPGRvb3I+KCk7CgoJc3RkOjpjb3V0IDw8IGJveS5zaXplPGRvb3I+KCkgPDwgc3RkOjplbmRsOwogICAgLy8gc3RkOjpjb3V0IDw8IGJveS5zaXplPGZvbz4oKSA8PCBzdGQ6OmVuZGw7ICAgLy8gY2Fubm90IHVzZSBmb28hCgoJcmV0dXJuIDA7Cn0=