在以下代码中,Derived
类的所有特化都应该是彼此的朋友。它在某种程度上起作用;但是,朋友声明似乎只允许某些成员访问。
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(); }
为什么Derived<Derived<int>>
可以访问Derived<Derived<float>>::i
(私有成员)而不是Derived<Derived<float>>::Base::i
(受保护成员)?
我怀疑问题可能与涉及部分专业化的事实有关。但是,严格来说,朋友声明并未声明部分专业化。此外,如果部分专业化是原因,为什么d.i
仍然有效?
简而言之,为什么d.i
有效但d.Base::i
无法解决?
修改:有趣的是,如果我们删除下面的部分特化,d.i
和d.Base::i
都可以正常工作。
class Base { protected: int i; };
template <typename T> class Derived : public Base {
template <typename U> friend class Derived;
int i;
public:
void f() {
Derived<float> d;
(void)d.i; // works fine
(void)d.Base::i; // also works fine
}
};
int main() { Derived<int>().f(); }