, я вижу то, что не могу объяснить в следующем коде. В VS6, VS9 и GCC T2 :: foo2 () выдает ошибку: 'bar': не может получить доступ к защищенному члену, объявленному в классе 'C1'. Но если вы удалите C1 :: bar (), он компилируется и работает правильно, даже несмотря на то, что T2 все еще обращается к защищенному C1B: bar (), что, как вы думаете, будет той же проблемой.
Обратите внимание, что в T2 :: foo2 () вы можете преобразовать 'pT1' в 'T1 *' и все в порядке, но это все еще не объясняет, почему C1B :: bar () разрешен, а C1 :: bar () нет.
template<class S> class T2;
template<class T> class T1
{
//template<class T> friend class T2; --> this doesn't compile under VS6
friend class T2<T>;
protected:
virtual void bar() { printf("T1\n"); }
};
template<class S> class T2
{
public:
void foo1(T1<S> *pT1) { pT1->bar(); } // --> ok, makes sense, this works either way
void foo2(S *pT1) { pT1->bar(); } // --> this fails to compile if C1::bar() is defined, but works for C1B::foo() ???
};
class C1 : public T1<C1>
{
protected:
virtual void bar() { printf("C1\n"); } // --> comment this out and foo2 will compile
};
class C1B : public C1
{
protected:
virtual void bar() { printf("C1B\n"); }
};
class C2 : public T2<C1>
{
};
void test(void)
{
C1B c1b;
C2 c2;
c2.foo1(&c1b);
c2.foo2(&c1b); // --> fails to compile if C1::bar() exists
}