ksl*_*ksl 14 c++ stdvector c++11 std-function
我有许多具有不同签名的回调函数.理想情况下,我想将它们放在一个向量中,并根据某些条件调用适当的一个.
例如
void func1(const std::string& value);
void func2(const std::string& value, int min, int max);
const std::vector<std::function<void(std::string)>> functions
{
func1,
func2,
};
Run Code Online (Sandbox Code Playgroud)
我意识到上述情况是不可能的,但我想知道是否有任何我应该考虑的替代方案.我还没有找到任何东西,我已经尝试过,std::bind但没有成功实现我想要的东西.
这样的事情可能吗?
Jon*_*ely 21
func2在将它放入错误类型的向量之后,您没有说过您希望能够做什么.
std::bind如果您提前知道参数,则可以轻松地将其放入向量中:
const std::vector<std::function<void(std::string)>> functions
{
func1,
std::bind(func2, std::placeholders::_1, 5, 6)
};
Run Code Online (Sandbox Code Playgroud)
现在functions[1]("foo")将调用func2("foo", 5, 6),并会把5并6于func2每一次.
使用lambda代替的是同样的事情 std::bind
const std::vector<std::function<void(std::string)>> functions
{
func1,
[=](const std::string& s){ func2(s, func2_arg1, func2_arg2); }
};
Run Code Online (Sandbox Code Playgroud)
如果您还不知道参数,可以绑定对某些变量的引用:
int func2_arg1 = 5;
int func2_arg2 = 6;
const std::vector<std::function<void(std::string)>> functions
{
func1,
std::bind(func2, std::placeholders::_1, std::ref(func2_arg1), std::ref(func2_arg2))
};
Run Code Online (Sandbox Code Playgroud)
现在functions[1]("foo")将调用func2("foo", func2_arg1, func2_arg2),您可以为整数分配新值以传递不同的参数func2.
并使用lambda函数代替 std::bind
const std::vector<std::function<void(std::string)>> functions
{
func1,
[&](const std::string& s){ func2(s, func2_arg1, func2_arg2); }
};
Run Code Online (Sandbox Code Playgroud)
这非常难看,因为int只要引用它们的可调用对象(闭包或绑定表达式)存在,就需要保持变量.
你想要什么是可能的polymorphism.我们的想法是创建一个具有特定签名的类,在运行时将调用不同的方法.例如:
#include <iostream>
#include <functional>
#include <memory>
#include <vector>
void foo(int) {
std::cout << "I'm foo!\n";
}
int bar(char, double) {
std::cout << "I'm bar!\n";
}
class MyFunction {
public:
virtual ~MyFunction(){}
virtual void operator()() = 0;
};
class MyFunctionA : public MyFunction {
public:
virtual void operator()() {
foo(4);
}
};
class MyFunctionB : public MyFunction {
public:
MyFunctionB(std::function<int(char,double)> f, char arg1, double arg2) : fun_(f), arg1_(arg1), arg2_(arg2) {}
virtual void operator()() {
fun_(arg1_, arg2_);
}
private:
std::function<int(char,double)> fun_;
char arg1_;
double arg2_;
};
int main() {
using MyFunPtr = std::unique_ptr<MyFunction>;
std::vector<MyFunPtr> v;
v.emplace_back(new MyFunctionA());
v.emplace_back(new MyFunctionB(bar, 'c', 3.4));
for ( auto&& myfun : v ) {
(*myfun)();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您可以根据需要使派生类变得复杂,但由于最终它们都具有相同的接口,因此您可以调用所有这些类.
| 归档时间: |
|
| 查看次数: |
10216 次 |
| 最近记录: |