Without long delay, here the code which I have no clue why it does what it does:
#include <iostream>
class A {
private:
void print() { std::cout << "A.print() called" << std::endl; };
public:
template<typename Foo>
class B; //NOTE: no friend!
public:
A();
B<double>* bd;
B<int>* bi;
};
template<typename Foo>
class A::B{
A* callback;
public:
B(A* a):callback(a){};
void print() { callback->print(); }; // Why is this working ???
};
A::A():bd(new B<double>(this)),bi(new B<int>(this)){}
int main(int argc, char **argv)
{
A a;
// a.print(); // error: ‘void A::print()’ is private
a.bd->print();
a.bi->print();
A::B<char> c(&a);
c.print();
A::B<double> d = *a.bd;
d.print();
return 0;
}
Well, it creates this ouput:
A.print() called
A.print() called
A.print() called
A.print() called
But why?
Background
I initially started my journey down the rabbit hole when I encountered a problem which I through to have to do with friend
s. So I read friend declaration not forward declaring (and the mentioned answers here and here). So while trying to set up an easy example (the result of which you see above), I found that I actually don't seem to need friend
at all.
Question
So here is the bottom line question: Why does an instance of A::B
have access to A
's private function A::print()
? (although I do realize that I might misunderstand what my children are--children as opposed to base vs. derived)