什么时候适用?
在开发工程时,经常会遇到一种情况,一开始用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);
}
结果