为什么不编译以下 CRTP 层次结构?

Why doesn't the following CRTP hierarchy compile?

本文关键字:层次结构 CRTP 编译 为什么不      更新时间:2023-10-16

我正在尝试实现类的CRTP层次结构。我对基类感兴趣,可以访问链下派生类的数据成员:

#include <iostream>
template <class Derived>
class A {
public:
void showv() {
std::cout << static_cast<const Derived*>(this)->v << std::endl;
}
};
template <class Derived>
class B : public A< Derived > {
typedef A<Derived> base;
friend base;
};
class fromA : public A<fromA> {
typedef A<fromA> base;
friend base;
protected:
int v = 1;
};
class fromB : public B<fromB>
{
typedef B<fromB> base;
friend base;
protected:
int v = 2;
};
int main()
{
// This runs ok
fromA derived_from_a;
derived_from_a.showv();
// Why doesn't the following compile and complains about the protected member?
fromB derived_from_b;
derived_from_b.showv();
return 0;
}

演示

虽然第一个派生类(fromA)按预期编译和运行,但第二个派生类(fromB)派生自A类,却没有。

  1. 朋友声明没有通过的原因是什么?
  2. 关于解决方法的任何建议?

问题是:我朋友的朋友不是我的朋友。

fromA你有

typedef A<fromA> base;
friend base;

这使得A<fromA>成为朋友,show可以访问fromA的受保护成员。

fromB你也有

typedef B<fromB> base;
friend base;

但这并不能使A成为朋友,而是使B成为你的朋友。 即使A是B的朋友,这并不意味着它现在也是fromB的朋友,这就是为什么您无法在show中访问v的原因。

解决此问题的一种方法是在B中公开或保护typedef A<Derived> base;然后在fromB中添加friend base::base;,从而授予A访问权限。