Объявление экземпляров вложенного базового шаблона класса друзьями производного класса - PullRequest
0 голосов
/ 26 апреля 2019

Предположим, у меня есть:

class A {};

template <typename T> class B {};

template <typename T> class C {};

class D : public C<B<A>> {
    //friend ... ??
};

Есть ли способ построить объявление друга для class D, чтобы экземпляр типа A был другом D. Экземпляр типа B<A> является другом D. и экземпляр типа C<B<A>> является другом D. И так далее для некоторого произвольного числа вложенных типов шаблонов, автоматически, без необходимости вручную указывать использование нескольких объявлений друзей в D?

Редактирование: Чтобы добавить некоторый контекст, желаемое приложение должно использовать стиль «связывания» интерфейсов CRTP с открытыми функциями, которые вызывают защищенные функции «переопределения» в классе реализации, дополнительные объявления «друга» немного уродливы, но не слишком обременительным, я думаю, для разумных длин композитных интерфейсов этого стиля.

#include <iostream>

template <typename T>
struct static_base {
  T& self() { return static_cast<T&>(*this); }
  T const& self() const { return static_cast<T const&>(*this); }
};

template <typename Derived>
class InterfaceBase : public static_base<Derived> {};

template <typename Derived>
class Interface1 : public Derived {
 public:
  void foo() { this->self().foo_(); }
};

template <typename Derived>
class Interface2 : public Derived {
 public:
  void bar() { this->self().bar_(); }
};

template <typename Derived>
class Interface3 : public Derived {
 public:
  void baz() { this->self().baz_(); }
};

class Impl : public Interface3<Interface2<Interface1<InterfaceBase<Impl>>>> {
    friend Interface3<Interface2<Interface1<InterfaceBase<Impl>>>>;
    friend Interface2<Interface1<InterfaceBase<Impl>>>;
    friend Interface1<InterfaceBase<Impl>>;

    protected:
        void foo_() { std::cout << "foo" << "\n"; }
        void bar_() { std::cout << "bar" << "\n"; }
        void baz_() { std::cout << "baz" << "\n"; }
};

int main() {
    auto impl = Impl();
    impl.foo();
    impl.bar();
    impl.baz();
}

1 Ответ

1 голос
/ 26 апреля 2019

Боюсь, вам придется дружить с каждым классом в отдельности.Вы не можете наследовать дружбу, поэтому я не думаю, что это можно сделать с помощью одной декларации друга.

...