#include <iostream>
using namespace std;
template < class T>
class Foo
{
protected :
static T* t;
friend T;
} ;
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+CmNsYXNzIEZvbwp7Cglwcm90ZWN0ZWQ6CglzdGF0aWMgVCogdDsKCWZyaWVuZCBUOwp9Owp0ZW1wbGF0ZSA8Y2xhc3MgVD4KVCogRm9vPFQ+Ojp0ID0gbnVsbHB0cjsKCnRlbXBsYXRlIDxjbGFzcyBTZWxmLCBjbGFzcyBUPiAvL1QgPSBUeXBlIGRlcml2ZWQgZnJvbSBGb28Kc3RydWN0IEJhcgp7Cgl2b2lkIHRlc3QoKQoJewoJCVQ6OnQgPSBzdGF0aWNfY2FzdDxTZWxmKj4odGhpcyk7Cgl9Cn07CgpzdHJ1Y3QgRm9vRGVyaXZlZDsKCnN0cnVjdCBCYXJEZXJpdmVkIDogcHVibGljIEJhcjxCYXJEZXJpdmVkLCBGb29EZXJpdmVkPgp7CgkKfTsKCnN0cnVjdCBGb29EZXJpdmVkIDogcHVibGljIEZvbzxCYXJEZXJpdmVkPgp7CgkKfTsKCmludCBtYWluKCkgewoJCglhdXRvIGEgPSBCYXJEZXJpdmVke307CglhLnRlc3QoKTsKCQoJcmV0dXJuIDA7Cn0=
compilation info
prog.cpp: In instantiation of ‘void Bar<Self, T>::test() [with Self = BarDerived; T = FooDerived]’:
prog.cpp:38:9: required from here
prog.cpp:12:4: error: ‘BarDerived* Foo<BarDerived>::t’ is protected
T* Foo<T>::t = nullptr;
^
prog.cpp:19:8: error: within this context
T::t = static_cast<Self*>(this);
^
stdout