struct B_crtp;
template<class Derived> struct B_crtp_base;

template<class Derived>
struct A_crtp_base {
    
    operator B_crtp_base<B_crtp>();
};

struct A_crtp : A_crtp_base<A_crtp> {
    };

template<class Derived> struct B_crtp_base : A_crtp_base<B_crtp_base<Derived>> {};

struct B_crtp : B_crtp_base<B_crtp> {};

template<class Derived>
A_crtp_base<Derived>::operator B_crtp_base<B_crtp>()
{
        return B_crtp_base<B_crtp>(); // Whatever, make sure this is set with common A_crtp_base stuff
}

int main() 
{
   A_crtp a;
   B_crtp b;

   static_cast< B_crtp_base<B_crtp>& >(b) = a;

   return 0;
}