Странное поведение друга шаблона C ++

, я вижу то, что не могу объяснить в следующем коде. В 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
}
6
задан Greg 11 May 2011 в 17:35
поделиться