【问题标题】:how to pass variadic params to virtual function如何将可变参数传递给虚函数
【发布时间】:2017-01-30 10:05:36
【问题描述】:

我有一个工作虚函数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;                                         
};        

【问题讨论】:

  • 当您使用auto ... 时,Func 不是具体类型。您需要将其设为模板别名,如:template&lt;typename ... Ts&gt; using Func = std::function&lt;xyz(Ts const &amp; ...)&gt;;
  • 您想将具有不同签名的函数添加到同一个cfExecuror,还是具有相同可变参数签名的函数,或其他?
  • 不同的签名会很好,但到目前为止我只想拥有接受可变参数的函数
  • @serup:你的目标和目标是什么?你想用这个做什么?我觉得如果你以不同的方式接近你的目标,你可能甚至不必用virtual 函数编写这个类。
  • @Nawaz,我有几个不同的执行器,一个叫做 ManualExecutor - 它工作正常,但是现在我想向我添加到执行器的函数添加参数 - 执行器正在执行承诺/未来

标签: c++ std-function variadic-functions


【解决方案1】:

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

这可以通过std::bind 完成。您无需以任何方式更改add 或添加基于vector&lt;variant&gt; 的重载。只需如下调用:

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));

将它与常规函数、成员函数、类函数对象(“函子”)或 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);

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

【讨论】:

  • 这就是我一直在寻找的 - 我会尝试相应地调整我的代码 - 谢谢
【解决方案2】:

AFAIK,你还不能在函数原型中使用'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
  • 我在以 cfExecutor 作为父类的类中使用此原则时遇到问题
  • 我对模板名称的使用无效 - 不太确定这个设置发生了什么,也许我不太了解你的解决方案 - 我在我的问题中添加了更多信息,你能再看看吗
  • @serup 不确定你是如何传递 lambda 的,它可能需要单独发布一篇文章
  • @P0W,是的,我可能同意另一篇文章 - 不知何故,为存储在队列中的 lambda 函数转发参数的问题并不是那么微不足道,但是很容易将 lambda 函数放在队列中以备后用执行,但是关于参数/参数传输的整个事情都隐藏在一些模板设置中,其中 pt。 lambdas 不可能使用 - 我认为
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-05
  • 1970-01-01
  • 2014-10-20
  • 2023-01-21
  • 1970-01-01
  • 2010-12-15
  • 2013-01-20
相关资源
最近更新 更多