如何将可变参数传递给虚函数

5

我有一个可用的虚函数add,它使用以下设置:

using Func = std::function<std::vector<unsigned char>()>;      

class cfExecutor {
public:
    cfExecutor();
    virtual ~cfExecutor();
    /// Enqueue a function to be executed by this executor. This and all                     
    /// variants must be threadsafe.
    virtual void add(Func) = 0;                              
    virtual void add(std::vector<Variant> params, Func callback) = 0; 
};


class ManualExecutor : public cfExecutor                                                                            
{                                                                                                                   

    std::mutex lock_;             // avoid multiple entity updating the function container                          
    std::queue<Func> funcs_;      // functions queued for running                                                 

    public:                                                                                                         
    std::map<int8_t, Func> funcs; // Function container (priority,Func) - added functions to this Executors       

    ManualExecutor() {}                                                                                             
    ManualExecutor(ManualExecutor&& other):                                                                         
                    funcs(std::move(other.funcs))                                                                   
    {}                                                                                                              
    ~ManualExecutor() {}                                                                                            

    void add(Func callback);                                                                          
    void add(std::vector<Variant> params, Func callback);                     
};                                                                                                                  

我想给这个函数添加可变参数,就像这样:

using Func = std::function<std::vector<unsigned char>(const auto&...args)>;  

然而,我遇到了隐式错误[隐式模板可能不是“虚拟的”]

我应该如何定义具有可变参数的add函数?

到目前为止,我使用以下方法解决了这个问题:

using Func = std::function<std::vector<unsigned char>(std::vector<Variant>)>;

然后让lambda函数从内部向量处理接收参数 - 就像这样:

auto lambdaFunction = [](std::vector<Variant> vec){        

    std::vector<unsigned char> result;                     
    cout << "- Hello from executor - lambdaFunction ";     
    std::cout << ": parameters : ";                        
    for(auto a: vec) {                                     
        std::cout << a << ",";                             
    }                                                      
    std::cout << std::endl;                                 

    std::string s("this is the result");                   
    result.insert(result.end(),s.begin(), s.end());        
    return result;                                         
};        

1
当你使用 auto ... 时,Func 不是一个具体类型。你需要将其作为模板别名,如下所示:template<typename ... Ts> using Func = std::function<xyz(Ts const & ...)>; - Nawaz
3
您是否想将具有不同签名的函数添加到同一个cfExecutor中,或者具有相同可变参数签名的函数,还是其他内容? - n. m.
@serup:你的目标和目的是什么?你想用这个做什么?我觉得如果你用不同的方式来实现你的目标,你可能甚至不需要编写带有“虚拟”函数的类。 - Nawaz
忘记C++规则。假设它们会让你随心所欲地弯曲类型。你有一堆带有未知数量和类型参数的函数。你为什么需要它们?你会如何使用它们? - n. m.
想象一下,你有一组 Lambda 函数排成队列,你可以从队列中获取这些 Lambda 并逐个执行它们,或者在新的线程中进行调用 - 我想做的是使用参数来完成这个操作 - 到目前为止,我已经成功地实现了无参 Lambda 的处理。 - serup
显示剩余17条评论
2个回答

2
据我所知,在函数原型中暂时无法使用'auto'。你可能想要按照以下方式进行操作:
template<typename ... Args >
using Func =std::function<std::vector<unsigned char>(const Args&...args)>;

template<typename ... Args >
class cfExecutor {                        
 public:   
     cfExecutor();                        
    virtual ~cfExecutor(); 
     virtual void add(Func<Args...>) = 0;

    };

请注意,在模板别名中不需要使用 args - Nawaz
我在使用这个原则时遇到了问题,因为这个类的父类是cfExecutor。 - serup
@P0W,是的,我同意也许需要另外一篇文章 - 在某种程度上,将参数转发给存储在队列中的lambda函数并不是那么简单,但是很容易将lambda函数放入队列以供稍后执行,然而有关参数/参数传递的整个问题都隐藏在某些模板设置中,这对于lambda函数来说是不可能使用的 - 我认为。 - serup
@POW,也许可以新建一个帖子并在此示例的基础上进行扩展: https://dev59.com/5X3aa4cB1Zd3GeqPYRe0#22109991 你认为如何向lambda表达式添加参数以及如何将参数转发给正在执行的lambda表达式? - serup
这篇文章是关于将参数传递给队列内的lambda函数,目前普通的模板设置不可行,因此有了这篇文章 - 那么如何做呢??? - serup
显示剩余4条评论

2

看起来您想传递一个绑定函数。

可以使用std::bind实现。您不需要以任何方式更改add或添加基于vector<variant>的重载。只需按以下方式调用即可:

std::vector<unsigned char> myfunction (int, const char*, Foo&);

...
int i = 123;
const char* s = "abc";
Foo foo{1,2,3};
executor->add(std::bind(myfunction, i, s, foo));

可以将其与普通函数、成员函数、函数式对象(“functors”)或 Lambda 表达式一起使用。但是,对于内联 Lambda 表达式来说,这并不太有意义,因为你可以在 Lambda 表达式本身中捕获数据。

executor->add([&i,s,&foo](){ ... use(i); use(s); use(foo); }

事实上,您总是可以用一个更易读的 lambda 替换 bind 表达式。比较一下:
int foo;
std::bind(std::operator<<, std::cout, foo);

vs

[foo]() { return std::cout << foo; }

这就是我一直在寻找的 - 我会尝试相应地调整我的代码 - 谢谢 - serup

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接