2017-01-30 100 views
4

我有一个正常运行的虚拟函数add它采用以下设置:如何可变参数PARAMS传递到虚拟函数

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

我当时就想可变参数PARAMS添加到功能 - 就像这样:

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

但是我得到隐含错误[隐模板可能不是“虚”]

我应该如何定义与一个可变PARAMS add函数?

到目前为止,我已经解决了它使用下列内容:

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

,然后有lambda函数从向量内办理接收ARGS - 这样的事情:

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

当您使用自动'...''然后是Func'没有具体类型。你需要使它成为一个模板的别名,如:'使用Func键=的std ::函数模板;' – Nawaz

+3

你想用不同的签名添加功能到相同的cfExecuror,或具有相同可变签名或其他功能的函数? –

+0

不同的签名将是很好的,但是SOFAR我只是想有功能,这需要可变参数PARAMS – serup

回答

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

将其与常规函数,成员函数,类函数对象(“函子”)或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; } 
+0

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

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; 

    }; 
+0

请注意,模板别名中不需要'args'。 – Nawaz

+0

我在使用此cfExecutor作为父母的类中使用此原则的问题 – serup

+0

我无法使用模板名称 - 不太确定此设置发生了什么,也许我不太了解您的解决方案 - 我添加了更多信息我的问题,你可以再看看 – serup

相关问题