vendredi 25 novembre 2016

Friend declaration grants access only to some members

In the following code, all specializations of the Derived class should be friends of each other. It works to some extent; however, the friend declaration seems to grant access only to some members.

class Base { protected: int i; };
template <typename T> class Derived;
template <typename T> class Derived<Derived<T>> : public Base {
  template <typename U> friend class Derived;
  int i;
 public:
  void f() {
    Derived<Derived<float>> d;
    (void)d.i;       // works fine, although i is private
    (void)d.Base::i; // error: 'int Base::i' is protected
  }
};
int main() { Derived<Derived<int>>().f(); }

Why can Derived<Derived<int>> access Derived<Derived<float>>::i (which is private member) but not Derived<Derived<float>>::Base::i (which is a protected member)?

I suspect the problem may have to do with the fact that a partial specialization is involved. However, strictly speaking, the friend declaration does not declare a partial specialization. Moreover, if the partial specialization was the reason, why does d.i still work?

In short, why does d.i work but not d.Base::i and how to fix it?

Aucun commentaire:

Enregistrer un commentaire