CRTP 中间类也需要成为 final
Posted
技术标签:
【中文标题】CRTP 中间类也需要成为 final【英文标题】:CRTP intermediate class that needs to also be made final 【发布时间】:2012-04-17 13:07:04 【问题描述】:我有一个 CRTP 类的继承链。 CRTP 类相互派生,直到“最终”派生类将自身作为 CRTP 参数传递并最终确定继承链。
template <class W>
struct Base
.....
;
template <class W>
struct Derived_inheritable: public Base<W>
....
template <class W>
struct Derived2_inheritable: public Derived_inheritable<W>
....
...
我想要做的是能够在 CRTP 继承链的每一层都有这样的“最终”最终用户类,不涉及模板:
typedef Derived1_inheritable<Derived1> Derived1;
你可以猜到,这个 typedef 不起作用,因为它引用了它自己定义的类型。问题是如何实现这一目标? 我能想到的方法是:
struct Derived1: public Derived1_inheritable<Derived1>
//not convenient, need to redefine at least a forwarding constructor
正如代码中的注释所说,这不是一个非常优雅的解决方案 - 我需要重新定义构造函数以转发到基本构造函数。有人知道更优雅的方式吗?
【问题讨论】:
我不能说你的例子很有启发性,而且问题的措辞是 final 的 intermediate 类,是自相矛盾的.你到底想达到什么目的? 这里的中间意味着我有相互派生的CRTP类,直到最终派生类将自己作为CRTP参数传递并最终确定继承链。我想要做的是能够在 CRTP 继承链的每个级别都有这样的“最终”类 【参考方案1】:typedef Derived1_inheritable Derived1;
那行没有意义,模板的参数是一个 type 但你试图传递一个 template (顺便说一下你正在实例化的同一个模板,但是除了这个额外的怪癖之外,事实是您的模板采用 type 作为参数,而您传递的是非类型)
从问题中并不清楚您要达到什么目标。你应该努力陈述你的目标,而不是你实现该目标的方法。
我想为每个非模板的 DerivedX_inheritable 创建一个“最终”类,并将自身作为 W 参数传递。
这正是在您提供的代码中完成的:
struct Derived1: public Derived1_inheritable<Derived1>
这是一个类型定义(创建一个“最终”类)。事实上,您的 CRTP 基础需要最终用户必须提供的参数以及转发构造函数的需要,这只是您设计的副作用。
【讨论】:
好吧,我认为最好的说明方法是编写显示类层次结构的代码。我猜 typedef 行是这里令人困惑的地方,所以我在第一个答案的评论中澄清了它。 是的,这是一个副作用,我正在寻找一种方法来弥补它,通过在每个级别定义不涉及模板的最终用户类。我正在寻找我找到的解决方案的替代解决方案,因为我不想创建(因此 typedef,如果可能的话)其他类(和构造函数) @AlexanderVassilev:不管你喜不喜欢,这就是你的设计所带来的。你在那里无能为力。您可以尝试编写一个宏来获取一些样板文件,但是您需要定义一个新类型,并且该类型必须有一个构造函数 我得出了同样的结论。没有其他方法可以实现这种设计的好处,因此与好处相比,这种不便之处非常小。感谢您的帮助。【参考方案2】:我想我找到了一个优雅的解决方案:
template <class W>
struct Base
.....
;
template <class W>
struct Derived_inheritable: public Base<W>
....
//solution
struct Derived2_dummy;
template <class W=derived2d_ummy>
struct Derived2_inheritable: public Derived_inheritable<W>
....
struct derived2_dummy: public: Derived_inheritable<>;
typedef Derived2_inheritable<> Derived2;
【讨论】:
以上是关于CRTP 中间类也需要成为 final的主要内容,如果未能解决你的问题,请参考以下文章
为什么Java匿名内部类访问的外部局部变量或参数需要被final修饰
在Java中String类为什么要设计成final?String真的不可变吗?其他基本类型的包装类也是不可变的吗?