为什么不能编译以下 CRTP 层次结构?
Why doesn't the following CRTP hierarchy compile?
我正在尝试实现 class 的 CRTP 层次结构。我对基数 class 感兴趣,可以访问链下派生 class 的数据成员:
#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;
}
虽然第一个派生的 class (fromA
) 按预期编译和运行,但第二个 (fromB
) 派生自 class 派生自 A
,没有。
- 朋友声明没有通过的原因是什么?
- 有任何解决方法的建议吗?
问题是:我朋友的朋友不是我朋友。
在fromA
你有
typedef A<fromA> base;
friend base;
这使 A<fromA>
成为朋友并且 show
可以访问 fromA
的受保护成员。
在fromB
你还有
typedef B<fromB> base;
friend base;
但这并不能使 A
成为朋友,而是 B
你的朋友。尽管 A 是 B
的朋友,但这并不意味着它现在也是 fromB
的朋友,这就是为什么您无法在 show
.[=28 中访问 v
的原因=]
解决此问题的一种方法是使 typedef A<Derived> base;
public 或在 B
中受到保护,然后在 fromB
中添加 friend base::base;
授予 A
访问权限。
我正在尝试实现 class 的 CRTP 层次结构。我对基数 class 感兴趣,可以访问链下派生 class 的数据成员:
#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;
}
虽然第一个派生的 class (fromA
) 按预期编译和运行,但第二个 (fromB
) 派生自 class 派生自 A
,没有。
- 朋友声明没有通过的原因是什么?
- 有任何解决方法的建议吗?
问题是:我朋友的朋友不是我朋友。
在fromA
你有
typedef A<fromA> base;
friend base;
这使 A<fromA>
成为朋友并且 show
可以访问 fromA
的受保护成员。
在fromB
你还有
typedef B<fromB> base;
friend base;
但这并不能使 A
成为朋友,而是 B
你的朋友。尽管 A 是 B
的朋友,但这并不意味着它现在也是 fromB
的朋友,这就是为什么您无法在 show
.[=28 中访问 v
的原因=]
解决此问题的一种方法是使 typedef A<Derived> base;
public 或在 B
中受到保护,然后在 fromB
中添加 friend base::base;
授予 A
访问权限。