如何使用具有不同模板参数的变量制作矢量?

时间:2016-07-02 12:38:49

标签: c++ function pointers vector function-pointers

我正在创建一个程序,所有按钮都需要在向量中,所以我可以使用for循环轻松地为所有按钮调用render函数。我创建了一个缩短版本的问题。所以下面的代码有一个名为Button的类。当我创建一个Button变量时,我必须发送包含我想要调用的函数的类和模板中的函数指针。当我按下按钮Pressed功能时,它将调用我发送的功能。当我调用按钮渲染功能时,它将渲染。然后,我有两个不同的类,其中的函数应该在按下相应的按钮时调用。我还没有使用过模板,所以我不确定如果按钮有不同的模板参数我会如何将按钮放入向量中,所以我不能写:

for (int i = 0; i < buttons.size(); i++) {
    buttons[i].Render();
}

而不是:

    button1.Render();
    button2.Render();
    button3.Render();
    but...

这是代码:

template<class CWF> //CWF = Class with Function
class Button {
public:
    typedef void(CWF::*eventMethod)();

    Button(CWF& cwf_, eventMethod method_) : method(method_), cwf(cwf_) {};
    ~Button() {}

    void Pressed() {
    (cwf.*(method))();
    }

    void Render() {};

private:
    eventMethod method;
    CWF& cwf;
};

Class1 class1;
Class2 class2;
Button<Class1> button1 = Button<Class1>(class1,&Class1::MyButtonWasPressed);
Button<Class2> button2 = Button<Class2>(class2, &Class2::MyButtonWasPressed);

int main() {

    // loop here
    button1.Render();
    button2.Render();
    //      

    //exiting herer
    string line;
    getline(cin, line);
    return 0;

}

1 个答案:

答案 0 :(得分:3)

您的示例中的最佳选择是完全删除模板,而是通过回调传递std::function

但是,如果您的需求足够复杂且不可行,则需要实现某种形式的类型擦除。最直观的方法是使模板类派生自一些提供所需功能的接口:

class AbstractButton {
public:
    virtual void Pressed() = 0;
    virtual void Render() const = 0;
};

template <typename CWF>
class Button : AbstractButton {
public:
    // ...
    void Pressed() override { /* ... */ }
    void Render() const override { /* ... */ }
};

使用:

// store in vector
std::vector<std::unique_ptr<AbstractButton>> buttons;
buttons.push_back(std::unique_ptr<AbstractButton>(new Button<Class1>(/* ... */)));
    // (or std::make_unique if you have C++14)

// use:
buttons[i]->Render();