Почему классу друзей C ++ нужно предварительное объявление только в других пространствах имен?

Предположим, у меня есть класс F , который должен дружить с классами G (в глобальном пространстве имен) и C (в пространстве имен A ).

  • чтобы дружить с A :: C , F должен быть объявлен вперед.
  • to быть другом G , предварительное объявление F не требуется.
  • аналогично, класс A :: BF может быть другом A :: C без предварительного объявления

Следующий код иллюстрирует это и компилируется с GCC 4.5, VC ++ 10 и, по крайней мере, с одним другим компилятором.

class G {
    friend class F;
    int g;
};

// without this forward declaration, F can't be friend to A::C
class F;

namespace A {

class C {
    friend class ::F;
    friend class BF;
    int c;
};

class BF {
public:
    BF() { c.c = 2; }
private:
    C c;
};

} // namespace A

class F {
public:
    F() { g.g = 3; c.c = 2; }
private:
    G g;
    A::C c;
};

int main()
{
    F f;
}

Мне это кажется несовместимым. Есть ли для этого причина или это просто проектное решение стандарта?

46
задан pesche 20 December 2010 в 17:15
поделиться