当前位置: 首页 > 知识库问答 >
问题:

带模板参数函数的C++向量

贺雪松
2023-03-14
#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
        

    }
};

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

共有1个答案

莘光华
2023-03-14

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

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

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

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...); });
    }
    void action()
    {
        for (auto& f: listener)
            f();
    }
    void print() { std::cout << "Button value -> " << val << std::endl; }
    
private:
    static std::vector<std::function<void()>> listener;
    
};

std::vector<std::function<void()>> Button::listener;

void test3(Button* b) {
    
    std::cout << "listened:";
    b->print();
}

void test4(int a) {
    
    std::cout << "print " << a << std::endl;
}

int main()
{
    Button* button = new Button(5);
    button->print();
    button->addListener(std::function<decltype(test4)>(&test4), 1);
    button->addListener(std::function<decltype(test3)>(&test3), button);
    button->action();
}

您也可以将监听器构造完全留给用户:

class Button
{
public:
    Button(int _val):val(_val){}
    ~Button();
    int val;
    
    void addListener(std::function<void()> f) {
        listener.push_back(f);
    }
    void action()
    {
        for (auto& f: listener)
            f();
    }
    void print() { std::cout << "Button value -> " << val << std::endl; }
    
private:
    static std::vector<std::function<void()>> listener;
    
};

std::vector<std::function<void()>> Button::listener;

void test3(Button* b) {
    
    std::cout << "listened:";
    b->print();
}

void test4(int a) {
    
    std::cout << "print " << a << std::endl;
}

int main()
{
    Button* button = new Button(5);
    button->print();
    button->addListener([]() { test4(1); });
    button->addListener([button]() { test3(button); });
    button->action();
}
 类似资料:
  • 我正在努力使用一个结构的友元函数,该结构有一个模板参数,如果 和 如果尝试编译,则会出现以下链接器错误: (带有。) 我希望操作符只处理具有相同模板参数的类型,例如,foo只处理foo,而不处理foo或foo。 我认为这与这个问题密切相关,但我很难弄清楚如何解决我的问题。我尝试了许多模板定义,如

  • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty

  • 如果我没有理解错的话,类模板定义了一个函数,所以当我调用时,编译器有可能进行隐式强制转换,但是在函数模板的情况下,此时没有函数定义,所以隐式强制转换不会发生。 但我不明白为什么编译器不能创建函数定义,然后应用隐式强制转换? 错误是: 在函数“int main()”中:    25:24:错误:调用“test2::add(void(&)(int))”没有匹配函数    25:24:注:候选人是:  

  • 受这个答案的启发,我生成了这段代码,其输出取决于编译器: 如果使用 GCC 11 编译,调用

  • 使用以下代码生成时 生成以下诊断(代码后): 诊断: 有趣的部分不是关于歧义错误本身(这不是这里主要关注的问题)。有趣的是,当仅使用函数名调用fun时,第一个fun的模板参数F被解析为纯函数类型double(double),而第二个fun的模板参数F被解析为更期望的函数指针类型。 然而,当我们将调用<代码>乐趣(测试) 更改为<代码>乐趣( 这种行为似乎是所有Clang和GCC(以及Visual

  • 以下是我的代码:< br > 一开始我只是重载了函数,发现有很多类似的代码。所以我正在考虑使用可变参数模板来获得更好的设计。(如果两个重载函数相似,如何做出更好的设计) 但是我不知道为什么会有错误:< br > main.cpp:27: 8:错误:没有匹配函数调用'getChar'ch=getChar(1, std::forward(str)...); 主要的cpp:37:2:注意:在函数模板专门

  • 假设有一个模板函数 接受任意数量的参数。给定最后一个参数始终是 ,我如何实现下面显示的 模板,以便 包含此 的参数? 例如,如果像这样调用,应该是: 我的第一个想法是: 但这不会编译: 问题一: 为什么这不能编译?为什么模板参数演绎失败? 最终,我想出了这个解决方案: 这里,是,即中的最后一种类型。然后,的临时值被传递到,其中。这行得通,但在我看来很难看。 问题二: 我想知道如果没有两个函数和的临

  • 我有这样的情况 这是我自己的Vector类,构造函数模拟了Vector的行为(u可以通过使用interator提供的数据范围来构造它),但增加了一个要求,即容器是与正在构造的容器相同类型的模板。我有错误 5.cpp:16:36:错误:调用“Vector::Vector(Vector::Iterator,Vector::Iterator)”没有匹配函数5.cpp:16:36:注意:候选项是:包含在5