2016-12-02 1 views
0

Я пытаюсь сохранить std::vector внутри класса с именем InputManager, который хранит слушателей.Как сохранить std :: vector, если тип нуждается в шаблоне

У меня есть суперкласс, который называется Listener. Этот класс имеет переменные с типами, хранящимися в шаблоне.

template <class obj> 
class Listener 

Производный класс определяет шаблон на основе типа слушателя:

class onClickListener : public Listener<Button*> 

Как я могу хранить std::vector из Listeners без определения типа?

std::vector<Listener<obj>> InputManager::listeners = std::vector<Listener<obj>>() 

class InputManager 
{ 
public: 
    template <class obj> 
    InputManager(GLFWwindow* window); 

    template <class obj> 
    void run(); 
    ~InputManager(); 
    static InputManager* Self; 
    template<class obj> 
    void addListener(Listener<obj>* listener); 
private: 
    GLFWwindow* window; 
    static std::vector<Listener<obj>> InputManager::listeners = std::vector<Listener<obj>>(); 
}; 

Если вам нужна дополнительная информация, пожалуйста, дайте мне знать.

+3

* CRTP * для статического полиморфизма. Если вы хотите, чтобы во время выполнения выполнялось полиморфное поведение (это то, что вы требуете, требуя элементов вектора, ссылающегося на разные динамические экземпляры), вам нужно не-шаблонное наследование. – Pixelchemist

+0

Как я могу сохранить способность сохранять эти переменные в Listener без шаблона? –

ответ

0

Без шаблона вы просто иметь простой нешаблонном базовый тип:

#include <vector> 
#include <iostream> 
#include <utility> 
#include <memory> 

struct listener { virtual void action() = 0; virtual ~listener() {} }; 

struct onClickListener : listener { 
    void action() override { std::cout << "click: " << this << '\n'; } 
}; 

struct input_manager 
{ 
    std::vector<listener*> listeners; 
    void add_listener(listener* lisp) 
    { 
     listeners.push_back(lisp); 
    } 
    void doit() const 
    { 
     for(auto&& lp : listeners) { if(lp) lp->action(); } 
    } 
}; 

int main() 
{ 
    input_manager mgr; 
    auto listen_a = std::make_unique<onClickListener>(); 
    auto listen_b = std::make_unique<onClickListener>(); 
    mgr.add_listener(listen_a.get()); 
    mgr.add_listener(listen_b.get()); 
    mgr.doit(); 
} 
Смежные вопросы