#include <iostream>
using namespace std;
struct B {};
struct A1 : B { void foo() { cout << "A1::foo()\n"; } };
struct A2 : B { void foo() { cout << "A2::foo()\n"; } };
struct A3 : B { void foo() { cout << "A3::foo()\n"; } };
struct A4 : B { void foo() { cout << "A4::foo()\n"; } };
struct C {
A1* p1;
A2* p2;
A3* p3;
A4* p4;
// ...
};
template <class D, size_t startNumber, size_t numMembers, bool notFinished>
struct FooCaller;
template <class D, size_t startNumber>
struct FooSingleCall;
template <class D, size_t startNumber, size_t numMembers>
struct FooCaller<D, startNumber, numMembers, false> {
void operator() (D& d) {}
};
template <class D, size_t startNumber, size_t numMembers>
struct FooCaller<D, startNumber, numMembers, true> {
void operator() (D& d) {
FooSingleCall<D,startNumber>()(d);
FooCaller<D, startNumber + 1, numMembers, startNumber < numMembers>()(d);
}
};
#define FooSingleCallD(n) \
template <class D> \
struct FooSingleCall<D,n>{ \
void operator() (D& d) { \
d.p##n->foo(); \
} \
}
FooSingleCallD(1);
FooSingleCallD(2);
FooSingleCallD(3);
FooSingleCallD(4);
// ... unfortunately repeat as many times as needed
template <class D, size_t numMembers>
void callFoo(D& d)
{
FooCaller<D, 1, numMembers, 1 <= numMembers>()(d);
}
int main() {
C c;
callFoo<C,4>(c);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKc3RydWN0IEIge307CnN0cnVjdCBBMSA6IEIgeyB2b2lkIGZvbygpIHsgY291dCA8PCAiQTE6OmZvbygpXG4iOyB9IH07CnN0cnVjdCBBMiA6IEIgeyB2b2lkIGZvbygpIHsgY291dCA8PCAiQTI6OmZvbygpXG4iOyB9IH07CnN0cnVjdCBBMyA6IEIgeyB2b2lkIGZvbygpIHsgY291dCA8PCAiQTM6OmZvbygpXG4iOyB9IH07CnN0cnVjdCBBNCA6IEIgeyB2b2lkIGZvbygpIHsgY291dCA8PCAiQTQ6OmZvbygpXG4iOyB9IH07CgpzdHJ1Y3QgQyB7CiAgQTEqIHAxOwogIEEyKiBwMjsKICBBMyogcDM7CiAgQTQqIHA0OwogIC8vIC4uLgp9OwoKdGVtcGxhdGUgPGNsYXNzIEQsIHNpemVfdCAgc3RhcnROdW1iZXIsIHNpemVfdCBudW1NZW1iZXJzLCBib29sIG5vdEZpbmlzaGVkPgpzdHJ1Y3QgRm9vQ2FsbGVyOwp0ZW1wbGF0ZSA8Y2xhc3MgRCwgc2l6ZV90ICBzdGFydE51bWJlcj4Kc3RydWN0IEZvb1NpbmdsZUNhbGw7Cgp0ZW1wbGF0ZSA8Y2xhc3MgRCwgc2l6ZV90ICBzdGFydE51bWJlciwgc2l6ZV90IG51bU1lbWJlcnM+CnN0cnVjdCBGb29DYWxsZXI8RCwgc3RhcnROdW1iZXIsIG51bU1lbWJlcnMsIGZhbHNlPiB7CiAgIHZvaWQgb3BlcmF0b3IoKSAoRCYgZCkge30KfTsKCnRlbXBsYXRlIDxjbGFzcyBELCBzaXplX3QgIHN0YXJ0TnVtYmVyLCBzaXplX3QgbnVtTWVtYmVycz4Kc3RydWN0IEZvb0NhbGxlcjxELCBzdGFydE51bWJlciwgbnVtTWVtYmVycywgdHJ1ZT4gewogICB2b2lkIG9wZXJhdG9yKCkgKEQmIGQpIHsKICAgICAgIEZvb1NpbmdsZUNhbGw8RCxzdGFydE51bWJlcj4oKShkKTsKICAgICAgIEZvb0NhbGxlcjxELCBzdGFydE51bWJlciArIDEsIG51bU1lbWJlcnMsIHN0YXJ0TnVtYmVyIDwgbnVtTWVtYmVycz4oKShkKTsKICAgfQp9OwoKI2RlZmluZSBGb29TaW5nbGVDYWxsRChuKSBcCnRlbXBsYXRlIDxjbGFzcyBEPiBcCnN0cnVjdCBGb29TaW5nbGVDYWxsPEQsbj57IFwKICAgdm9pZCBvcGVyYXRvcigpIChEJiBkKSB7IFwKICAgICAgIGQucCMjbi0+Zm9vKCk7IFwKICAgfSBcCn0KCkZvb1NpbmdsZUNhbGxEKDEpOwpGb29TaW5nbGVDYWxsRCgyKTsKRm9vU2luZ2xlQ2FsbEQoMyk7CkZvb1NpbmdsZUNhbGxEKDQpOwovLyAuLi4gdW5mb3J0dW5hdGVseSByZXBlYXQgYXMgbWFueSB0aW1lcyBhcyBuZWVkZWQKCnRlbXBsYXRlIDxjbGFzcyBELCBzaXplX3QgbnVtTWVtYmVycz4Kdm9pZCBjYWxsRm9vKEQmIGQpCnsKICAgRm9vQ2FsbGVyPEQsIDEsIG51bU1lbWJlcnMsIDEgPD0gbnVtTWVtYmVycz4oKShkKTsKfQoKaW50IG1haW4oKSB7CiAgIEMgYzsKICAgY2FsbEZvbzxDLDQ+KGMpOwp9Cgo=