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

class private_object
{
private:
  struct make_public;
  friend struct make_public;
  static void method1() {}
};

struct private_object::make_public
{
  class nested_outer
  {
    void callFromOuter() 
    { private_object::method1(); }   // Should this be an error?

    class nested_inner
    {
      void callFromInner() 
      { private_object::method1(); } // How about this one?
    };
  };
};

Эта проблема дружбы возникла, когда я пытался портировать проект с открытым исходным кодом для компиляции под Borland. Согласно parashift и двум полусвязанным вопросам здесь и здесь , приведенный выше пример недопустим.

Однако после тестирования его на семи разных компиляторах 1 пожаловались только borland и dmc. Такое поведение удивило меня, потому что я не ожидал, что дружба будет транзитивной во вложенных классах.

Таким образом, возникает пара вопросов:

  • Какое поведение является правильным? Я предполагаю, что это тот, который принят большинством компиляторов.
  • Если это правильное поведение, почему этот пример транзитивности дружбы в порядке?
  • Если это правильно, то это также будет означать изменение стандарта. Каковы могут быть причины для разрешения этого в стандарте?
  • Для компиляторов, которые отклонили этот код, какое решение может быть подходящим? Имейте в виду, что реальный проект может содержать довольно глубокую вложенность, поэтому я ищу решение, которое является полумасштабируемым.

1. протестировано на mingw-gcc 4.5.2, clang, borland c ++ builder2007, digital mars, open watcom, visualc2010 и comeau online

5
задан Andrew Brēza 16 November 2017 в 12:05
поделиться