如何解决如何使用一张地图存储不同的功能
void func(int type,int a,int b) {
std::string str = "hello";
switch (type) {
case 1: {
func1(a,b);
break;
}
case 2: {
func2(a,b,str);
break;
}
// hundreds of cases...
}
}
我想改变这个可怕的功能,因为它有太多的案例。
好消息是每个 case 只调用一个函数,该函数必须使用 a
和 b
作为它的第一个和第二个参数。坏消息是其中一些可能需要第三个参数。
我在考虑是否可以使用 std::map<int,std::function<void(int,int,...)>>
来存储案例中的所有函数,但它不起作用。 std::function
似乎不能接受可变参数函数。
还有其他方法吗?
解决方法
std::any
将成为您的朋友。再加上一些包装类和包装类中的模板函数,隐藏any cast,会更直观一些。
它会给你更多的可能性。
请看:
#include <iostream>
#include <map>
#include <string>
#include <any>
#include <utility>
class Caller
{
std::map<int,std::any> selector;
public:
Caller() : selector() {}
Caller(std::initializer_list<std::pair<const int,std::any>> il) : selector(il) {}
template<typename Function>
void add(int key,Function&& someFunction) { selector[key] = std::any(someFunction); };
template <typename ... Args>
void call(int key,Args ... args) {
if (selector.find(key) != selector.end()) {
std::any_cast<std::add_pointer_t<void(Args ...)>>(selector[key])(args...);
}
}
};
// Some demo functions
void a(int x) {
std::cout << "a\t" << x << '\n';
};
void b(int x,int y) {
std::cout << "b\t" << x << '\t' << y << '\n';
};
void c(int x,int y,std::string z) {
std::cout << "c\t" << x << '\t' << y << '\t' << z << '\n';
};
void d(std::string s,int x,int z) {
std::cout << "d\t" << s << '\t' << x << '\t' << y << '\t' << z << '\n';
};
// Definition of our caller map (using initializer list)
Caller caller{
{1,a},{2,b},{3,c} };
int main() {
// Some demo calls
caller.call(1,1);
caller.call(2,1,2);
caller.call(3,2,std::string("3"));
// Adding an additional function
caller.add(4,d);
// And call this as well.
caller.call(4,std::string("ddd"),3);
return 0;
}
,
你可以像 lambda 那样包装
void func(int type,int a,int b) {
std::string str = "hello";
std::map<int,std::function<void(int,int)>> m {
{1,[](int a,int b) { func1(a,b); } },[str](int a,int b) { func2(a,b,str); } },...
};
m[type](a,b);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。