【发布时间】:2017-06-26 11:54:14
【问题描述】:
我想了解是否可以在基 CRTP 类中使用叶 CRTP 类的嵌套类。下面的示例演示了该问题。
#include <iostream>
using namespace std;
template<class T>
class A
{
protected:
T* asLeaf(void)
{return static_cast<T*>(this);}
T const* asLeaf(void) const
{return static_cast<T const*>(this);}
public:
struct Inner
{int a = 10;};
void dispInner(void) const
{std::cout << asLeaf()->inner.a << std::endl;}
// I would like to use T::Inner in this class, e.g.
// typename T::Inner mvInnerA;
// However, I understand that it is not possible to
// use it in the form that is stated above. Thus,
// I am looking for any possible workarounds.
};
class B: public A<B>
{
public:
struct Inner: public A<B>::Inner
{int b = 20;};
protected:
friend A<B>;
B::Inner inner;
public:
void dispInner(void) const
{
A<B>::dispInner();
std::cout << asLeaf()->inner.b << std::endl;
}
};
int main()
{
B b;
b.dispInner();
return 0;
}
编辑
我想根据收到的反馈再提供几个 cmet:
- 我知道我可能没有使用足够的设计实践。特别是
A是否应该知道inner的存在可能会受到质疑。但是,我想在A中定义B::Inner类型的对象inner,而不是在B中提供inner的定义并在A中使用它。 - 我知道我无法转发声明
B和/或B::Inner以及无法转发的原因。因此,从技术上讲,设计问题没有解决方案。不过,我正在寻找可行的解决方法。
我已经考虑了几种替代解决方案:
- 一种可能的可行解决方案是不要尝试在
A中“定义”B::Inner inner,并使用A的成员函数来提供允许修改@987654337 的A<B>::Inner部分的功能@。 - 另一种可能的解决方案是明确定义
A<B>::Inner和B::Inner类(即不作为嵌套类)。但是,我宁愿避免这种情况,因为根据设计,任何不派生自A的类都不需要与A<B>::Inner或派生自A<B>::Inner的类交互
我提出的两种解决方案都可以接受。但是,我正在寻找任何可行的替代方案。
【问题讨论】:
-
一般规则是你的基类不应该知道它的孩子,你正在引入循环依赖,这是不好的
-
@lapinozz 这就是他使用 CRTP (en.wikipedia.org/wiki/Curiously_recurring_template_pattern) 的原因,这并没有错。
-
@lapinozz - 您正在考虑动态多态性,它与 CRTP 的静态多态性完全正交。不一定适用相同的“规则”。
-
我明白了,我的错,但是问题出在哪里?注释代码似乎很好,错误是什么?
-
@lapinozz 感谢您的评论。我相信您在回答我的问题的原始规范时所说的内容是正确的。但是,请参阅我在问题末尾制作的 cmets。
标签: c++ inner-classes forward-declaration crtp