#include <iostream>
#include <memory>
#include <type_traits>
struct TagA { } ;
struct TagB { } ;
template < typename tp_Derived >
struct BaseCRTP;
struct Base
{
template < typename > friend
struct BaseCRTP;
private : void
handler_impl( const std:: shared_ptr < Base> & ) { }
} ;
template < typename tp_Derived >
struct BaseCRTP: public Base
{
public : void
handler( const std:: shared_ptr < Base> & obj)
{
static_assert
(
:: std :: is_base_of < TagA, tp_Derived > :: value
, "\" handler\" method can only be used in classes deriving from TagA"
) ;
return ( handler_impl( obj) ) ;
}
} ;
struct DerivedA : BaseCRTP< DerivedA > , TagA
{ } ;
struct DerivedB : BaseCRTP< DerivedB > , TagB
{ } ;
int main( )
{
DerivedA a; // OK
( void ) a; // not used
auto pha( & DerivedA:: handler ) ; // OK
DerivedB b; // OK
( void ) b; // not used
auto phb( & DerivedB:: handler ) ; // static_assertion failure
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgpzdHJ1Y3QgVGFnQSB7fTsKc3RydWN0IFRhZ0Ige307Cgp0ZW1wbGF0ZTwgdHlwZW5hbWUgdHBfRGVyaXZlZCA+CnN0cnVjdCBCYXNlQ1JUUDsKCnN0cnVjdCBCYXNlCnsKCXRlbXBsYXRlPCB0eXBlbmFtZSA+IGZyaWVuZAoJc3RydWN0IEJhc2VDUlRQOwoKCXByaXZhdGU6IHZvaWQKCWhhbmRsZXJfaW1wbChjb25zdCBzdGQ6OnNoYXJlZF9wdHI8QmFzZT4gJikge30KfTsKCnRlbXBsYXRlPCB0eXBlbmFtZSB0cF9EZXJpdmVkID4Kc3RydWN0IEJhc2VDUlRQOiBwdWJsaWMgQmFzZQp7CglwdWJsaWM6IHZvaWQKCWhhbmRsZXIoY29uc3Qgc3RkOjpzaGFyZWRfcHRyPEJhc2U+ICYgb2JqKQoJewoJCXN0YXRpY19hc3NlcnQKCQkoCgkJCTo6c3RkOjppc19iYXNlX29mPCBUYWdBLCB0cF9EZXJpdmVkID46OnZhbHVlCgkJLAkiXCJoYW5kbGVyXCIgbWV0aG9kIGNhbiBvbmx5IGJlIHVzZWQgaW4gY2xhc3NlcyBkZXJpdmluZyBmcm9tIFRhZ0EiCgkJKTsKCQlyZXR1cm4oaGFuZGxlcl9pbXBsKG9iaikpOwoJfQp9OwoKc3RydWN0IERlcml2ZWRBIDogQmFzZUNSVFA8IERlcml2ZWRBID4sIFRhZ0EKe307CgpzdHJ1Y3QgRGVyaXZlZEIgOiBCYXNlQ1JUUDwgRGVyaXZlZEIgPiwgVGFnQgp7fTsKCmludCBtYWluKCkKewoJRGVyaXZlZEEgYTsgLy8gT0sKCSh2b2lkKSBhOyAvLyBub3QgdXNlZAoJYXV0byBwaGEoJkRlcml2ZWRBOjpoYW5kbGVyKTsgLy8gT0sKCURlcml2ZWRCIGI7IC8vIE9LCgkodm9pZCkgYjsgLy8gbm90IHVzZWQKCWF1dG8gcGhiKCZEZXJpdmVkQjo6aGFuZGxlcik7IC8vIHN0YXRpY19hc3NlcnRpb24gZmFpbHVyZQoJcmV0dXJuIDA7Cn0=
compilation info
prog.cpp: In instantiation of ‘void BaseCRTP<tp_Derived>::handler(const std::shared_ptr<Base>&) [with tp_Derived = DerivedB]’:
prog.cpp:48:22: required from here
prog.cpp:26:3: error: static assertion failed: "handler" method can only be used in classes deriving from TagA
static_assert
^~~~~~~~~~~~~
stdout