#include<iostream>
struct B {};
struct C { B m1, m2; };
#define TRAIT_C(N, FUNCTION) \
template<> \
struct Trait##N<C> \
{ \
static \
void foo(C t) \
{ \
Trait##N<B>::foo(t.m##N); \
} \
}
template<typename T>
struct Trait1
{
static
void foo(T t)
{}
};
template<>
struct Trait1<B>
{
static
void foo(B t)
{ std::cout << "Trait1<B>::foo()\n"; }
};
TRAIT_C(1, foo);
template<typename T>
struct Trait2
{
static
void foo(T t)
{}
};
template<>
struct Trait2<B>
{
static
void foo(B t)
{ std::cout << "Trait2<B>::foo()\n"; }
};
TRAIT_C(2, foo);
int main ()
{
C c;
Trait1<C> t1c;
t1c.foo(c);
}
I2luY2x1ZGU8aW9zdHJlYW0+CgpzdHJ1Y3QgQiB7fTsKc3RydWN0IEMgeyBCIG0xLCBtMjsgfTsKCiNkZWZpbmUgVFJBSVRfQyhOLCBGVU5DVElPTikgXAogIHRlbXBsYXRlPD4gXAogIHN0cnVjdCBUcmFpdCMjTjxDPiBcCiAgeyBcCiAgICBzdGF0aWMgXAogICAgdm9pZCBmb28oQyB0KSBcCiAgICB7IFwKICAgICAgVHJhaXQjI048Qj46OmZvbyh0Lm0jI04pOyBcCiAgICB9IFwKICB9CiAgICAgIAp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdHJ1Y3QgVHJhaXQxCnsKICAgIHN0YXRpYwogICAgdm9pZCBmb28oVCB0KQogICAge30KfTsKCnRlbXBsYXRlPD4Kc3RydWN0IFRyYWl0MTxCPgp7CiAgc3RhdGljCiAgdm9pZCBmb28oQiB0KQogIHsgc3RkOjpjb3V0IDw8ICJUcmFpdDE8Qj46OmZvbygpXG4iOyB9Cn07ClRSQUlUX0MoMSwgZm9vKTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBUcmFpdDIKewogICAgc3RhdGljCiAgICB2b2lkIGZvbyhUIHQpCiAgICB7fQp9OwoKdGVtcGxhdGU8PgpzdHJ1Y3QgVHJhaXQyPEI+CnsKICBzdGF0aWMKICB2b2lkIGZvbyhCIHQpCiAgeyBzdGQ6OmNvdXQgPDwgIlRyYWl0MjxCPjo6Zm9vKClcbiI7IH0KfTsKVFJBSVRfQygyLCBmb28pOwoKaW50IG1haW4gKCkKewogIEMgYzsKICBUcmFpdDE8Qz4gdDFjOwogIHQxYy5mb28oYyk7Cn0=