Say that a base class A defines a protected member. A derived class B uses this member.
A
B
class A { public: A(int v) : value(v) { }
There is actually a loophole using member pointers (no casting, no copying):
void B::compare_and_print(const A& other) const { auto max_value = std::max(value, other.*(&B::value)); std::cout << "Max value: " << max_value << "\n"; }