#include <iostream>
#include <vector>
#include <type_traits>
#include <memory>
using namespace std;
struct Slave {
virtual char const* Type() = 0;
};
template<typename T>
struct Slave_T : public Slave{
typedef T type;
virtual char const* Type() {
return typeid( T ).name();
}
};
template <typename ...T>
struct Master {
Master()
{
MakeSlave<T...,_my_centinel_type>();
cout << "All Slaves:" << endl;
for (auto const& slave : v){
cout << slave ->Type() << endl;
}
}
private:
struct _my_centinel_type {};
template<typename U, typename ...Rest>
typename std::enable_if<!std::is_same<U,_my_centinel_type>::value , void>::type MakeSlave()
{
v.push_back( std::make_shared<Slave_T<U>>());
MakeSlave<Rest...>();
}
template<typename U>
typename std::enable_if<std::is_same<U,_my_centinel_type>::value , void>::type MakeSlave(){
}
vector<shared_ptr<Slave>> v;
};
int main()
{
Master<int, double, char> m;
//Print("Hello", '!', 123, 123);
return 0;
}
ICAgICNpbmNsdWRlIDxpb3N0cmVhbT4KICAgICNpbmNsdWRlIDx2ZWN0b3I+CiAgICAjaW5jbHVkZSA8dHlwZV90cmFpdHM+CiAgICAjaW5jbHVkZSA8bWVtb3J5PgogICAgdXNpbmcgbmFtZXNwYWNlIHN0ZDsKICAgIAogICAgCiAgICAKICAgIHN0cnVjdCBTbGF2ZSB7CiAgICAJdmlydHVhbCBjaGFyIGNvbnN0KiBUeXBlKCkgPSAwOwogICAgfTsKICAgIAogICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICAgIHN0cnVjdCBTbGF2ZV9UIDogcHVibGljIFNsYXZlewogICAgCXR5cGVkZWYgVCB0eXBlOwogICAgCXZpcnR1YWwgY2hhciBjb25zdCogVHlwZSgpIHsKICAgIAkJcmV0dXJuIHR5cGVpZCggVCApLm5hbWUoKTsKICAgIAl9CiAgICB9OwogICAgCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgLi4uVD4KICAgIHN0cnVjdCBNYXN0ZXIgewogICAgCU1hc3RlcigpCiAgICAJewogICAgCQlNYWtlU2xhdmU8VC4uLixfbXlfY2VudGluZWxfdHlwZT4oKTsKICAgIAkJY291dCA8PCAiQWxsIFNsYXZlczoiIDw8IGVuZGw7CiAgICAJCWZvciAoYXV0byBjb25zdCYgc2xhdmUgOiB2KXsKICAgIAkJCWNvdXQgPDwgc2xhdmUgLT5UeXBlKCkgPDwgZW5kbDsKICAgIAkJfQogICAgCX0KICAgIHByaXZhdGU6CiAgICAgICAgc3RydWN0IF9teV9jZW50aW5lbF90eXBlIHt9OwogICAgCiAgICAJdGVtcGxhdGU8dHlwZW5hbWUgVSwgdHlwZW5hbWUgLi4uUmVzdD4KICAgIAl0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwhc3RkOjppc19zYW1lPFUsX215X2NlbnRpbmVsX3R5cGU+Ojp2YWx1ZSAsIHZvaWQ+Ojp0eXBlIE1ha2VTbGF2ZSgpCiAgICAJewogICAgICAgICAgICAgICAgdi5wdXNoX2JhY2soIHN0ZDo6bWFrZV9zaGFyZWQ8U2xhdmVfVDxVPj4oKSk7CiAgICAJCU1ha2VTbGF2ZTxSZXN0Li4uPigpOwogICAgCX0KICAgIAogICAgICAgIHRlbXBsYXRlPHR5cGVuYW1lIFU+CiAgICAJdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8c3RkOjppc19zYW1lPFUsX215X2NlbnRpbmVsX3R5cGU+Ojp2YWx1ZSAsIHZvaWQ+Ojp0eXBlIE1ha2VTbGF2ZSgpewogICAgCQkKICAgIAl9CiAgICAKICAgIAl2ZWN0b3I8c2hhcmVkX3B0cjxTbGF2ZT4+IHY7CiAgICB9OwogICAgCiAgICBpbnQgbWFpbigpCiAgICB7CiAgICAJTWFzdGVyPGludCwgZG91YmxlLCBjaGFyPiBtOwogICAgCS8vUHJpbnQoIkhlbGxvIiwgJyEnLCAxMjMsIDEyMyk7CiAgICAJcmV0dXJuIDA7CiAgICB9