Ben*_*itz 6 c++ templates circular-dependency mixins crtp
在这里解读循环继承的好方法是什么?
class Node {
// ...
public:
list<Node*> neighbors() { /* ... */ }
void update() { }
}
template<class NodeType>
class HasImportance : public virtual NodeType {
double m_importance = 0.0;
public:
void receive_importance(double imp) { /* ... */ }
void give_importance() {
for (auto neighbor : this->neighbors())
neighbor->receive_importance(m_importance /* ... */);
}
};
class TrafficLight : public HasImportance<TrafficLight>, virtual Node {
public:
list<TrafficLight*> neighbors() { ... }
void update() { give_importance(); /* ... */ }
};
Run Code Online (Sandbox Code Playgroud)
它失败了(gcc 4.7.0),因为TrafficLight当HasImportance尝试从它继承时它是一个不完整的类型.
真正的问题是HasImportance需要知道返回的类型
neighbors().如果HasImportance继承自
Node,则认为neighbors()返回列表
Node*,而不是TrafficLight*,因此不知道它可以调用receive_importance()项目.类似的问题,如果HasImportance不继承.
顺便说一句,我正在尝试做的是制作一些混音,以帮助轻松定义各种不同类型的图形,并分别对每个混音进行单元测试.例如,我应该能够通过编写类似的东西来定义交通信号灯图的节点类class TrafficLight : public HasImportance, HasState<3>,
virtual Node { }.
我想出了三种解决方法,但看起来都很难看.(1)
static_cast<NodeType*>.(2)TrafficLight将其传递
this给HasImportance它的构造函数.这样,
HasImportance根本不需要继承; 它只存储指向(ahem)本身的指针,而template参数提供指针的类型.(3)创建Node一个类模板,如下所示:
template<class NodeType>
class Node {
public:
list<NodeType*> neighbors() { /* ... */ }
}
class TrafficLight : public HasImportance<Node<TrafficLight>> { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
编译并没有引入无偿副本this,但似乎......有点太好奇了.
这里有代码味道吗?我应该以完全不同的方式处理这些图表吗?
(3) 但略有不同。
template <class NodeType>
class Node { ... };
template<class NodeType>
class HasImportance : public virtual Node<NodeType> { ... };
class TrafficLight : public HasImportance<TrafficLight> { ... };
Run Code Online (Sandbox Code Playgroud)
对我来说看起来完全简单,并不比 CRTP 本身更好奇。
| 归档时间: |
|
| 查看次数: |
367 次 |
| 最近记录: |