C++map处理条件分发

什么时候适用?

在开发工程时,经常会遇到一种情况,一开始用switch能处理的简单变化,随着工程的不断迭代维护,会发现case里执行的内容越来越多,这时候,整个switch就显得异常的臃肿,这种情况就可以通过map来优化,每个case封装成一个函数,根据key值,对应的函数地址,直接调用该函数。使得代码一下变得清晰起来

如何使用map模拟swicth?

定义一个map,其中key为条件,value为当前key的函数地址

最简单的入门写法
#include <iostream> // std::cou
#include <map>
using namespace std;
map<string, void (*)()> func_map;
void FuncA(){
	cout << "This is FuncA" << endl;
}

void FuncB(){
	cout << "This is FuncB" << endl;
}

void InitMapFunc(){
	func_map.insert(make_pair<string, void (*)()>("FuncA", &FuncA));
	func_map.insert(make_pair<string, void (*)()>("FuncB", &FuncB));
	func_map.insert(make_pair<string, void (*)()>("Lambda", [] { cout << "This is Lambda" << endl; }));
}

void* FindFuncByName(string func_key){
	auto it = func_map.find(func_key);
	if (it != func_map.end()) {
		return it->second;
	}
	return nullptr;
}

int main()
{
	InitMapFunc();
	string func_name1  = "FuncA";
	string func_name2  = "FuncC";
	string func_lambda = "Lambda";
	auto   func_1      = FindFuncByName(func_name1);
	auto   func_2      = FindFuncByName(func_name2);
	auto   func_3      = FindFuncByName(func_lambda);

	if (func_1) {
		func_map[func_name1]();
	}
	if (func_2) { //为nullptr 不执行
		func_map[func_name2]();
	}
	if (func_3) {
		func_map[func_lambda]();
	}
}
进阶之typedef
#include <iostream> // std::cou
#include <map>
#include <functional>
using namespace std;
typedef void(*Typedef_Void)();
map<string, Typedef_Void> func_map_typedef;

void FuncA(){
	cout << "This is FuncA" << endl;
}

void FuncB(){
	cout << "This is FuncB" << endl;
}

void InitMapFunc(){
	func_map_typedef.insert(make_pair<string, Typedef_Void>("FuncA", &FuncA));
	func_map_typedef.insert(make_pair<string, Typedef_Void>("FuncB", &FuncB));
	func_map_typedef.insert(make_pair<string, Typedef_Void>("Lambda", [] {
		cout << "This is Lambda Func" << endl;
	}));
}

int  main()
{
	InitMapFunc();
	string func_name1 = "FuncA";
	string func_name2 = "FuncC";
	string func_lambda = "Lambda";

	Typedef_Void f1 = func_map_typedef[func_name1]; 
	Typedef_Void f2 = func_map_typedef[func_name2]; 
	Typedef_Void f3 = func_map_typedef[func_lambda]; 
	if (f1) {	f1();	}
	if (f2) {   f2();   }
	if (f3) {   f3();   }           
	return 0;
}
C++ 11进阶写法 std::function封装器
  • 类模板 std::function 是通用多态函数封装器。
  • 是 C++ 中现有的可调用实体的一种类型安全的包裹(相对来说,函数指针的调用术语是不类型安全的)
  • std::function的实例能存储、复制及调用任何可调用目标:函数、 lambda 表达式、 bind 表达式或其他函数对象,还有指向成员函数指针和指向数据成员指针。
#include <iostream> // std::cou
#include <map>
#include <functional>
using namespace std;
std::function<void()>  void_fuc;
map<string, std::function<void()>> func_map_c11;
void FuncA(){
	cout << "This is FuncA" << endl;
}

void FuncB(){
	cout << "This is FuncB" << endl;
}

void InitMapFunc(){
	func_map_c11.insert(make_pair<string, std::function<void()>>("FuncA", FuncA));
	func_map_c11.insert(make_pair<string, std::function<void()>>("FuncB", FuncB));
	func_map_c11.insert(make_pair<string, std::function<void()>>("Lambda", [] { 
		cout << "This is Lambda Func" << endl;
	}));
}

void DoFunc(string func_key) {
	auto it = func_map_c11.find(func_key);
	if (it != func_map_c11.end()) {
		 it->second();
	}
}
int  main()
{
	InitMapFunc();
	string func_name1 = "FuncA";
	string func_name2 = "FuncC";
	string func_lambda = "Lambda";

	DoFunc(func_name1);
	DoFunc(func_name2);
	DoFunc(func_lambda);

	return 0;
}

进阶之类成员函数及带参调用

#include <iostream> // std::cou
#include <map>
#include <functional>
using namespace std;
class CMapFunc {
public:
	typedef void (CMapFunc::*FUNC)(int a); //需要加上作用域限制

	CMapFunc(){
		func_map.insert(make_pair<string, FUNC>("FuncA", &CMapFunc::FuncA));
		func_map.insert(make_pair<string, FUNC>("FuncB", &CMapFunc::FuncB));
		func_map_c11.insert(make_pair<string, std::function<void(CMapFunc*, int)>>(
			"FuncA", &CMapFunc::FuncA));
		func_map_c11.insert(make_pair<string, std::function<void(CMapFunc*, int)>>(
			"FuncB", &CMapFunc::FuncB));
	};
	~CMapFunc(){};

	void CallFunc(string func_name, int value) {
		auto it = func_map.find(func_name);
		if (it != func_map.end()) {
			(this->*func_map[func_name])(value); 
		}
		
	}
	void CallFunc_c11(string func_name, int value){
		auto it_c11 = func_map_c11.find(func_name);
		if (it_c11 != func_map_c11.end()) {
			it_c11->second(this, value);
		}
	}

private:
	void FuncA(int value) { cout << "This is FuncA value=" << value << endl; }
	void FuncB(int value) { cout << "This is FuncB value=" << value << endl; }

private:
	map<string, std::function<void(CMapFunc*, int)>> func_map_c11;
	map<string, FUNC> func_map;
};

int main()
{
	CMapFunc* test = new CMapFunc();
	test->CallFunc("FuncA", 26);
	test->CallFunc("FuncB", 27);
	test->CallFunc("FuncC", 27);
	test->CallFunc_c11("FuncA", 66);
	test->CallFunc_c11("FuncB", 67);
	test->CallFunc_c11("FuncC", 68);
}

结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值