#include <iostream>
using namespace std;
template <class T>
class Foo
{
protected:
static T* t;
template <class Self, class U> //T = Type derived from Foo
friend struct Bar;
};
template <class T>
T* Foo<T>::t = nullptr;
template <class Self, class T> //T = Type derived from Foo
struct Bar
{
void test()
{
T::t = static_cast<Self*>(this);
}
};
struct FooDerived;
struct BarDerived : public Bar<BarDerived, FooDerived>
{
};
struct FooDerived : public Foo<BarDerived>
{
};
int main() {
auto a = BarDerived{};
a.test();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGUgPGNsYXNzIFQ+CmNsYXNzIEZvbwp7CnByb3RlY3RlZDoKICAgIHN0YXRpYyBUKiB0OwogICAgdGVtcGxhdGUgPGNsYXNzIFNlbGYsIGNsYXNzIFU+IC8vVCA9IFR5cGUgZGVyaXZlZCBmcm9tIEZvbwogICAgZnJpZW5kIHN0cnVjdCBCYXI7Cn07CnRlbXBsYXRlIDxjbGFzcyBUPgpUKiBGb288VD46OnQgPSBudWxscHRyOwoKdGVtcGxhdGUgPGNsYXNzIFNlbGYsIGNsYXNzIFQ+IC8vVCA9IFR5cGUgZGVyaXZlZCBmcm9tIEZvbwpzdHJ1Y3QgQmFyCnsKCXZvaWQgdGVzdCgpCgl7CgkJVDo6dCA9IHN0YXRpY19jYXN0PFNlbGYqPih0aGlzKTsKCX0KfTsKCnN0cnVjdCBGb29EZXJpdmVkOwoKc3RydWN0IEJhckRlcml2ZWQgOiBwdWJsaWMgQmFyPEJhckRlcml2ZWQsIEZvb0Rlcml2ZWQ+CnsKCn07CgpzdHJ1Y3QgRm9vRGVyaXZlZCA6IHB1YmxpYyBGb288QmFyRGVyaXZlZD4KewoKfTsKCmludCBtYWluKCkgewoKCWF1dG8gYSA9IEJhckRlcml2ZWR7fTsKCWEudGVzdCgpOwoKCXJldHVybiAwOwp9Cg==