Доступ друзей в защищенный вложенный класс - PullRequest
11 голосов
/ 27 августа 2010

У меня есть следующий код C ++:

class A {
 protected:
  struct Nested {
    int x;
  };
};

class B: public A {
  friend class C;
};

class C {
  void m1() {
    B::Nested n; // or A::Nested
  }
};

Компилируя этот фрагмент с g ++ 4.4, не имеет значения, использую ли я B :: Nested или A :: Nested в m1.Clang принимает B::Nested, но не компилируется, если я A::Nested.Это ошибка в g ++ или в clang?

Ответы [ 2 ]

8 голосов
/ 27 августа 2010

Согласно Стандарту, GCC является правильным, а Clang - неправильным.Он говорит в 11.2 / 4

Член m доступен, когда назван в классе N, если

  • m как член N защищен, и ссылка происходит вчлен или друг класса N, или член или друг класса P, производный от N, где m как член P является частным или защищенным

Это предмет этого Clangотчет об ошибках, который не позволяет Clang построить Qt: http://llvm.org/bugs/show_bug.cgi?id=6840.Один парень из Clang говорит:

На самом деле, я намеренно еще не реализовал это правило.Это либо ошибка редакции, либо ужасная ошибка.Он нейтрализует весь «защищенный» спецификатор, делает правильную форму кода зависимой от существования совершенно не связанных классов, накладывает большие затраты на реализацию и формально неразрешима при наличии шаблонов.

1 голос
/ 27 августа 2010

В C ++ друзья не переходные.Друзья ваших друзей не обязательно являются моими друзьями.

Делая Nested защищенным в A, вы указываете, что все подклассы могут использовать этот элемент, но никто другой не может использовать его.Вы можете считать это своего рода другом.A делает всех подклассов друзьями в отношении доступа к вложенной структуре.

Теперь B делает C другом, но это не значит, что C также является другом A. Поэтому C не должен иметь доступа к Nested.

НО: поведение изменено с C ++ 03.В C ++ 03 вложенный класс является полноправным членом включающего класса и поэтому имеет полные права доступа.Дружба по-прежнему НЕ транзитивна, но теперь ее член имеет доступ.

Возможно, вы захотите взглянуть на http://www.rhinocerus.net/forum/language-c-moderated/578874-friend-transitive-nested-classes.html,, который объясняет аналогичную проблему.

...