首页 > 解决方案 > 继承带有约束的模板(不是 C+20 意义上的)

问题描述

来自 JavaScript 我一直在思考他们的事件和处理程序。因此,我想做一些 C++ 的对应物。我期待最终产品会出现这种行为

// Button.cpp
void press(const Vector2f& pos){ //Vector2f - vector of 2 floats in math sense
   if(this->check_if_inside(pos))
      this->evoke(Button::Event::ButtonPressed{});
}

// Controller.cpp
void init() {
   Button button{/*some params*/};
   button.addEventListener(Button::Event::ButtonPressed, []{
      std::cout << "I'm pressed!";
   });

   this->buttons[0] = button;
}

void loop() {
   while(auto e = window_events.poll()){
      if(e.type == eType::MouseClick){
         for(auto& button : this->buttons)
            button.press(e.pos);
      }
   }
}

我已经尝试通过这个“Eventable”类包装器一般地实现它

template <class C>
class Eventable {
    // We expect that class C being Eventable has some Event struct inside of it;
    typedef typename C::Event CEvent;
    // And a corresponding enum of possible types
    typedef typename CEvent::EventType CEventType;

    std::list<std::function<void(const CEvent&)>> event_listeners{};
public:
// other stuff like .addEventHandler and so on
};

但是当我尝试使用它时

class Button: public Eventable<Button> {
    struct Event {
        enum struct EventType {ButtonPressed}
        EventType type;
    
        struct ButtonPressed {};
    };
}

我收到编译器错误,不知道“按钮”的“事件”是什么(它说“不正确使用不完整类型的“类按钮”)。而且没有办法向前声明 Button::Event。所以问题是 -有没有办法让它工作?如何对模板说“嘿,你想从我这里获得一个事件子类,在这里,你有它”?

标签: c++templatesc++17wrapper

解决方案


推荐阅读