c ++ 带有模板参数的函数向量

Has*_*dmr 5 c++ templates vector addeventlistener

#include<iostream>
#include<functional>
#include <unordered_set>
#include <vector>
#include <unordered_map>
#include <variant>




class Button
{
public:
    Button(int _val):val(_val){}
    ~Button();
    int val;
    
    template<typename F, typename...InArgs>
    void addListener(std::function<F(InArgs...)>(f), InArgs... args) {
        listener.push_back(f(args...));
    }

    template<typename F, typename...InArgs>
    void callMethod(std::function<F(InArgs...)>(f), InArgs... args) {
        f(args...);
    }
    
    void print() { std::cout << "Button value -> " << val << std::endl; }
private:
    template<typename F,typename...InArgs>
    static std::vector<std::function<F(InArgs...)>> listener;
    
};

inline void test1() {
    std::cout << "Printing test1 method...\n";
}
inline void test2(Button* b) {
    std::cout << "Button value is 20.\n";
    b->val = 20;
}
inline void test3(Button* b, int a) {
    std::cout << "Button value is passed parameter.\n";
    b->val = a;
}
inline void test4(int a) {
    std::cout << "print " << a << std::endl;
}
class AppThree
{
public:
    static void run() {
        Button* button = new Button(5);
        button->print();
        //button->callMethod(std::function<void(int)>(&test4), 1); //work it
        button->addListener(std::function<void(int)>(&test4),1); // error
        

    }
};
Run Code Online (Sandbox Code Playgroud)

我想要将带有参数的函数推送到向量。我想从 vector 调用所有函数,但我不能添加函数。我收到 C3245 错误。我不知道哪里失败了。如果我的想法不正确,请显示正确的方式。对不起,我的英语不好:D

mol*_*ilo 2

您有一个成员变量模板侦听器,这意味着每种函数类型都有一个向量。编译器无法推断出您指的是哪一个。
\n您还尝试push_back调用函数的结果,而不是函数本身,并且您没有存储参数。

\n

您不能按照您计划的方式执行此操作,因为listener不是一个具有不同类型元素的变量 \xe2\x80\x93 它是(可能)许多变量,每个变量都有不同的类型。
\n为了调用它们,您需要枚举变量实例,但这是不可能的。
\n此外,您还需要找出某种方法来存储参数。

\n

由于您想稍后传递参数,因此您只需要一种类型,并且可以在 lambda 中捕获它们:

\n
class Button\n{\npublic:\n    Button(int _val):val(_val){}\n    ~Button();\n    int val;\n    \n    template<typename F, typename...InArgs>\n    void addListener(std::function<F(InArgs...)> f, InArgs... args) {\n        listener.push_back([=]() { f(args...); });\n    }\n    void action()\n    {\n        for (auto& f: listener)\n            f();\n    }\n    void print() { std::cout << "Button value -> " << val << std::endl; }\n    \nprivate:\n    static std::vector<std::function<void()>> listener;\n    \n};\n\nstd::vector<std::function<void()>> Button::listener;\n\nvoid test3(Button* b) {\n    \n    std::cout << "listened:";\n    b->print();\n}\n\nvoid test4(int a) {\n    \n    std::cout << "print " << a << std::endl;\n}\n\nint main()\n{\n    Button* button = new Button(5);\n    button->print();\n    button->addListener(std::function<decltype(test4)>(&test4), 1);\n    button->addListener(std::function<decltype(test3)>(&test3), button);\n    button->action();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

您还可以将侦听器构造完全留给用户:

\n
class Button\n{\npublic:\n    Button(int _val):val(_val){}\n    ~Button();\n    int val;\n    \n    void addListener(std::function<void()> f) {\n        listener.push_back(f);\n    }\n    void action()\n    {\n        for (auto& f: listener)\n            f();\n    }\n    void print() { std::cout << "Button value -> " << val << std::endl; }\n    \nprivate:\n    static std::vector<std::function<void()>> listener;\n    \n};\n\nstd::vector<std::function<void()>> Button::listener;\n\nvoid test3(Button* b) {\n    \n    std::cout << "listened:";\n    b->print();\n}\n\nvoid test4(int a) {\n    \n    std::cout << "print " << a << std::endl;\n}\n\nint main()\n{\n    Button* button = new Button(5);\n    button->print();\n    button->addListener([]() { test4(1); });\n    button->addListener([button]() { test3(button); });\n    button->action();\n}\n
Run Code Online (Sandbox Code Playgroud)\n