我有Consequence
,Event
和EventsConsequences
个类。
每个Event
派生类都有Consequence
个对象的列表,它触发存储在EventsConsequences
对象中。如果两个Event
对象属于同一类型(类),则它们必须触发相同的Consequence
s。
所以在EventsConsequences
课程中我有:
unordered_map<std::type_index, std::vector<Consequence*>> consequences;
template<typename Event>
void add_trigger_of(Consequence *consequence) {
consequences[typeid(Event)].push_back(consequence);
}
template<typename Event>
void trigger_consequences_of(Event *event) {
for (Consequence *consequence : consequences[typeid(Event)]);
consequence->react_to(event);
}
在Event
课程中:
EventsConsequences* consequences;
void trigger() {
consequences->trigger_consequences_of(this);
}
当然,我有很多Event
和Consequence
的派生类。
我想要的是它的工作,但它没有。它总是调用
EventsConsequences::trigger_consequences_of<Event>(Event*)
但不是派生类。
我必须解决这个问题的唯一方法是使Event::trigger()
virtual
和每个派生类重写它
void DerivedEvent::trigger() override {
consequences->trigger_consequences_of(this);
}
但我讨厌编写WET代码。还有其他方法吗?
答案 0 :(得分:3)
使用奇怪的重复模板模式(CRTP):
template <typename Derived>
struct Base {
void foo() {
func(static_cast<Derived*>(this));
}
};
struct A : Base<A> { };
struct B : Base<B> { };
int main() {
A a;
B b;
a.foo();
b.foo();
}
答案 1 :(得分:2)
您应该使用对象的动态类型的type_index
而不是类型模板参数的type_index
来访问地图。
consequences[typeid(*event)]
确保Event
至少有一个虚拟功能。