0
votes

Suppose I have:

class A {};

template <typename T> class B {};

template <typename T> class C {};

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

Is there a way to construct a friend declaration for class D such that an instance of type A is a friend of D. An instance of type B<A> is a friend of D. and an instance of type C<B<A>> is a friend of D. And so on for some arbitrary number of nested template types, automatically, without having to manually specify using multiple friend declarations in D?

Edit: To add some context the desired application is to use a style of "chaining" CRTP interfaces with public functions that call protected "override" functions in the implementation class, the extra "friend" declarations are a little ugly but not too onerous I guess for sane lengths of composited interfaces of this style.

#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
It looks like you're writing mixins. It might be cleaner if you use multiple inheritance. That won't get rid of the multiple friend declarations though.Indiana Kernick

1 Answers

1
votes

You'll have to friend each class individually I'm afraid. You can't inherit friendships so I don't think it's possible to do this with one friend declaration.