#include <string>
#include <tuple>
#include <iostream>
template<typename Tuple, std::size_t... Is>
void print_tuple(const Tuple& tup, std::index_sequence<Is...>);
template<typename Tuple>
using tuple_indices = std::make_index_sequence<std::tuple_size<Tuple>::value>;
template<typename... Ts>
class B {
public:
B(int i, bool b, float f, const Ts&... rest) :
properties(std::make_tuple(i, b, f, rest...)) {
}
virtual std::string id() const = 0;
std::tuple<int, bool, float, Ts...> properties;
};
class A : public B<float, std::string, std::string> {
using B::B;
virtual std::string id() const {
return "Class A";
}
};
class C : public B<std::string> {
using B::B;
virtual std::string id() const {
return "Class C";
}
};
template<typename... Ts>
void test(const B<Ts...>& base) {
std::cout << base.id() << '(';
print_tuple(base.properties, tuple_indices<decltype(base.properties)>{});
std::cout << ')' << std::endl;
}
int main() {
A foo(12, true, 3.14, 6.28, "foo", "bar");
C baz(36, false, .33, "baz");
test(foo);
test(baz);
}
template<typename Tuple, std::size_t... Is>
void print_tuple(const Tuple& tup, std::index_sequence<Is...>) {
using dummy = int[];
static_cast<void>(dummy {
0, (static_cast<void>(std::cout << (Is ? ", " : "") << std::get<Is>(tup)), 0)...
});
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8aW9zdHJlYW0+CiAKdGVtcGxhdGU8dHlwZW5hbWUgVHVwbGUsIHN0ZDo6c2l6ZV90Li4uIElzPgp2b2lkIHByaW50X3R1cGxlKGNvbnN0IFR1cGxlJiB0dXAsIHN0ZDo6aW5kZXhfc2VxdWVuY2U8SXMuLi4+KTsKIAp0ZW1wbGF0ZTx0eXBlbmFtZSBUdXBsZT4KdXNpbmcgdHVwbGVfaW5kaWNlcyA9IHN0ZDo6bWFrZV9pbmRleF9zZXF1ZW5jZTxzdGQ6OnR1cGxlX3NpemU8VHVwbGU+Ojp2YWx1ZT47CiAKdGVtcGxhdGU8dHlwZW5hbWUuLi4gVHM+CmNsYXNzIEIgewpwdWJsaWM6CiAgICBCKGludCBpLCBib29sIGIsIGZsb2F0IGYsIGNvbnN0IFRzJi4uLiByZXN0KSA6CiAgICAgICAgICAgIHByb3BlcnRpZXMoc3RkOjptYWtlX3R1cGxlKGksIGIsIGYsIHJlc3QuLi4pKSB7CiAgICB9CiAgICB2aXJ0dWFsIHN0ZDo6c3RyaW5nIGlkKCkgY29uc3QgPSAwOwogICAgc3RkOjp0dXBsZTxpbnQsIGJvb2wsIGZsb2F0LCBUcy4uLj4gcHJvcGVydGllczsKfTsKIApjbGFzcyBBIDogcHVibGljIEI8ZmxvYXQsIHN0ZDo6c3RyaW5nLCBzdGQ6OnN0cmluZz4gewogICAgdXNpbmcgQjo6QjsKICAgIHZpcnR1YWwgc3RkOjpzdHJpbmcgaWQoKSBjb25zdCB7CiAgICAJcmV0dXJuICJDbGFzcyBBIjsKICAgIH0KfTsKIApjbGFzcyBDIDogcHVibGljIEI8c3RkOjpzdHJpbmc+IHsKICAgIHVzaW5nIEI6OkI7CiAgICB2aXJ0dWFsIHN0ZDo6c3RyaW5nIGlkKCkgY29uc3QgewogICAgCXJldHVybiAiQ2xhc3MgQyI7CiAgICB9Cn07CiAKdGVtcGxhdGU8dHlwZW5hbWUuLi4gVHM+CnZvaWQgdGVzdChjb25zdCBCPFRzLi4uPiYgYmFzZSkgewoJc3RkOjpjb3V0IDw8IGJhc2UuaWQoKSA8PCAnKCc7CiAgICBwcmludF90dXBsZShiYXNlLnByb3BlcnRpZXMsIHR1cGxlX2luZGljZXM8ZGVjbHR5cGUoYmFzZS5wcm9wZXJ0aWVzKT57fSk7CiAgICBzdGQ6OmNvdXQgPDwgJyknIDw8IHN0ZDo6ZW5kbDsKfQogCmludCBtYWluKCkgewogICAgQSBmb28oMTIsIHRydWUsIDMuMTQsIDYuMjgsICJmb28iLCAiYmFyIik7CiAgICBDIGJheigzNiwgZmFsc2UsIC4zMywgImJheiIpOwogCiAgICB0ZXN0KGZvbyk7CiAgICB0ZXN0KGJheik7Cn0KIAp0ZW1wbGF0ZTx0eXBlbmFtZSBUdXBsZSwgc3RkOjpzaXplX3QuLi4gSXM+CnZvaWQgcHJpbnRfdHVwbGUoY29uc3QgVHVwbGUmIHR1cCwgc3RkOjppbmRleF9zZXF1ZW5jZTxJcy4uLj4pIHsKICAgIHVzaW5nIGR1bW15ID0gaW50W107CiAgICBzdGF0aWNfY2FzdDx2b2lkPihkdW1teSB7CiAgICAgICAgMCwgKHN0YXRpY19jYXN0PHZvaWQ+KHN0ZDo6Y291dCA8PCAoSXMgPyAiLCAiIDogIiIpIDw8IHN0ZDo6Z2V0PElzPih0dXApKSwgMCkuLi4KICAgIH0pOwp9