switch-case 采用map+函数指针替代
个人觉得不能一味排斥和推崇采用其他方法替代switch-case。
但如果对于一些情况采用map+函数指针去替代switch会极大的优化代码,整洁和使代码不会那么膨胀。
对于多个函数的参数相同的情况下,采用map+函数指针。
对于函数在类内处理方法有两种:
1.因为map的时候要取函数地址指针,将函数单独开辟地址空间采用static(这个方法不好)
2.采用提前声明,用函数指针。(推荐这种)
class A;
using Func = int (A::*)(int);
3.采用map+function+bind方法,用函数指针。(推荐这种)
比如:分别case 为1,2,3 分别执行不同的函数,如果有很多函数就会导致代码臃肿。
class A
{
public:int test1(int a);int test2(int a);int test3(int a);int GetTest(int a);
};
int A::test1(int a)
{return 1;
}
int A::test2(int a)
{return 2;
}
int A::test3(int a)
{return 3;
}
int A::GetTest(int a)
{int data = 0;switch (a){case 1:data = test1(10);break;case 2:data = test1(10);break;case 3:data = test1(10);break;default:break;}return data;
}
int main()
{A a;int data = a.GetTest(1);return 0;
}
通过map+函数指针可以处理这种情况。
需要注意:先声明一下类,然后用类型别名 注意用A::*。(这种处理是函数在类内的时候要这么处理),主要是要取函数的地址指针。不采用这个方法也行,可以把函数加static处理,单独给函数开辟一个地址,不建议这么处理。
函数被取出了的时候要用
(this->*data->second)(a);
不然会报错:明显调用的表达式前的括号必须具有(指针)函数类型
class A;
using Func = int (A::*)(int);
using namespace std;
class A;
using Func = int (A::*)(int);
class A
{
public:void initMap();int test1(int a);int test2(int a);int test3(int a);optional<int> GetTest(int a);
private:map<int, Func> infoMap;
};
int A::test1(int a)
{return 1;
}
int A::test2(int a)
{return 2;
}
int A::test3(int a)
{return 3;
}
void A::initMap()
{map<int, Func> dataMap = {{1,&A::test1},{2,&A::test2},{3,&A::test3},};infoMap.swap(dataMap);
}//C++17 optinal<T>等于bool +其类型T
optional<int> A::GetTest(int a)
{optional<int> info;if (auto data = infoMap.find(a); infoMap.end()!= data){info = (this->*data->second)(a);}return info;
}
int main()
{A a;a.initMap();optional<int> data = a.GetTest(1);if (!data.has_value()){cout << "has no tag" << endl;}elsecout << "data is :" << *data << endl;return 0;
}
3.map+function+bind
using namespace std;using Func = function<int(int)>;
class A
{
public:void initMap();int test1(int a);int test2(int a);int test3(int a);optional<int> GetTest(int a);
private:map<int, Func> infoMap;
};
int A::test1(int a)
{return 1;
}
int A::test2(int a)
{return 2;
}
int A::test3(int a)
{return 3;
}
void A::initMap()
{map<int, Func> dataMap = {{1,std::bind(&A::test1,this, std::placeholders::_1)},{2,std::bind(&A::test2,this, std::placeholders::_1)},{3,std::bind(&A::test3,this, std::placeholders::_1)},};infoMap.swap(dataMap);
}//C++17 optinal<T>等于bool +其类型T
optional<int> A::GetTest(int a)
{optional<int> info;if (auto data = infoMap.find(a); infoMap.end() != data){info = data->second(a);}return info;
}
int main()
{A a;a.initMap();optional<int> data = a.GetTest(1);if (!data.has_value()){cout << "has no tag" << endl;}elsecout << "data is :" << *data << endl;return 0;
}
4.采用map+可变模板参数+function+bind方法,用函数指针
针对于多参数的test函数可以采用可变参数模版进行处理,但仍有限制的地方
限制的地方:
1.map中的func必须指定参数类型。
2.进行变量输入需要额外指定。
template<typename... Args>
using func = function<int(Args...)>;
class A
{
public:void initMap();int test1(int a, string b);int test2(int a);template<typename... Args>int findMap(int num, Args...);
private:map<int, func<int,string>> infoMap;
};int A::test1(int a,string b)
{return 1;
}
int A::test2(int a)
{return 2;
}void A::initMap()
{map<int, func<int,string>> dataMap = {{1,std::bind(&A::test1,this, std::placeholders::_1,std::placeholders::_2)},{2,std::bind(&A::test2,this, std::placeholders::_1)},};infoMap.swap(dataMap);
}template<typename... Args>
int A::findMap(int num,Args... args)
{auto iter = infoMap.find(num);if (iter!= infoMap.end()){return iter->second(args...);}return 0;
}int main(void)
{A a;a.initMap();cout << a.findMap(1, 1, "") << endl;cout << a.findMap(2,5,"string") << endl;return 0;
}
5.采用map+function+any+bind方法,处理多参数函数(推荐这种)
using func = function<int(any)>;
class A
{
public:A();int test1(any data);int test2(any data);int findMap(int num,any data);
private:map<int, func> infoMap;
};int A::test1(any data)
{//对any进行处理return 1;
}
int A::test2(any data)
{//对any进行处理return 2;
}A::A()
{map<int, func> dataMap = {{1,std::bind(&A::test1,this, std::placeholders::_1)},{2,std::bind(&A::test2,this, std::placeholders::_1)},};infoMap.swap(dataMap);
}int A::findMap(int num, any data)
{auto iter = infoMap.find(num);if (iter!= infoMap.end()){return iter->second(data);}return 0;
}struct TypeA
{
public:TypeA(const int& i, const string& s) :x(i), str(s) {};int x;string str;
};struct TypeB
{
public:TypeB(const int& i, const double& s) :x(i), y(s) {};int x;double y;
};int main(void)
{A a;TypeA ta(10,"test");TypeB tb(20, 30);any dataA = ta, dataB = tb;cout << a.findMap(1, dataA) << endl;cout << a.findMap(2, dataB) << endl;return 0;
}
switch-case 采用map+函数指针替代相关推荐
- c语言map函数指针,函数指针 - 弧光守望者 - OSCHINA - 中文开源技术交流社区
/*Author:Choas Lee *Date:2012-02-28 */ #include #include #include float add(float a,float b){return ...
- java中map函数指针_如何用Rust编写合适的map函数?
使用以下链接列表定义: enum List { Nil, Cons(T, ~List) } 我正在尝试编写一个map函数(即将操作应用于列表的每个元素并返回一个新列表) . 我正在尝试使用教程中提供的 ...
- java map函数指针_C 函数指针与回调函数
关于回调函数的一点思考 在 A 函数中将参数与 C 函数传递给 B 函数,B函数调用 C 函数:B 函数调用的动作称为回调,C 函数称为回调函数. 举栗 #include // 回调函数a void ...
- 函数指针及其的运用(上)——何为函数指针
=========================引子========================= 我们都知道,数组名就是指向数组第一个元素的常量指针(详见<数组拾遗>).同理,对于 ...
- linux C 学习---函数指针
我们经常会听到这样的说法,不懂得函数指针就不是真正的C语言高手.我们不管这句话对与否,但是它都从侧面反应出了函数指针的重要性,所以我们还是有必要掌握对函数指针的使用.先来看看函数指针的定义吧. 函数是 ...
- C++函数指针数组的使用方法
2015-11-24 一. 缘起 什么情况下,想到将函数指针数组来的呢?是由于近期写的一个程序中,有一系列顺序化的函数,且这些函数的形式基本一致,需要对每一步的执行结果进行判断,是否执行成功,若执 ...
- C++使用switch动态获取函数(通过函数指针实现)
C++使用switch动态获取函数(通过函数指针实现) 基本的就不再赘述了,以下使用三种方法完成根据不同情况动态获取函数的功能. 方法一:通过形参取地址获得函数指针 这种方式的好处是可以通过传入多个取 ...
- MATLAB Simulink中自定义函数和switch case的用法
文章目录 1 Simulink自定义函数MATLAB Function 2 Simulink中Switch Case模块的用法 1 Simulink自定义函数MATLAB Function 首先写一个 ...
- c++容器(vector|map)中使用函数指针
我要动态生成mfc菜单,动态绑定响应命令. 首先把菜单关键词和函数指针绑定在map中, 再通过关键词找到函数来执行. #include "stdafx.h" #include &l ...
最新文章
- HDU5977 Garden of Eden 【FMT】【树形DP】
- MYSQL数据库VALUES_MYSQL入门大全来啦!
- Java Enterprise软件与应有的软件
- Java实现动画逐字打印
- cacti监控java,Cacti监控tomcat的方法
- android中常用的开源项目
- android 签名打包 Invalid keystore format
- DuckDuckGo + Alfred
- 用Windows Media Service打造的流媒体直播系统
- 思科网络安全 第七章测验答案
- 微信JSApi支付~订单号和微信交易号
- Tex(文档排版工具)
- ssh服务器配置以及密匙登录
- 中文字符 简体繁体相互转换
- ubuntu 设置静态路由_ubuntu配置静态路由及重启生效
- FFmpeg之sws_scale库的应用(sws_getContext、sws_scale、sws_freeContext)
- 【测试】测试执行流程
- GUI,UGUI,NGUI三种编辑UI界面的插件
- Filter_编码过滤,登录过滤,权限过滤
- 解一元二次方程ax2+bx+c=0的解。