Доступ друзей к защищенному вложенному классу

У меня есть следующий код 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 , но не компилируется, если I A :: Nested . Это ошибка в g ++ или в clang?

11
задан Torsten Marek 27 August 2010 в 13:03
поделиться

2 ответа

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

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

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

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

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

8
ответ дан 3 December 2019 в 10:24
поделиться

В 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, где объясняется аналогичная проблема. .

1
ответ дан 3 December 2019 в 10:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: