1、实现代码: ==关注头文件 ==
// table_map.h
#ifndef TABLE_MAP_H
#define TABLE_MAP_H
#include <iostream>
#include <map>
#include <utility>
#include <initializer_list>
#include <functional>
using namespace std;
template <class key, class func = std::function<void()>, class tb_map = std::map<key, func>>
class table_driven
{
public:
using value_type = typename tb_map::value_type;
table_driven() = default;
~table_driven() = default;
public:
// 使用初始化列表初始化
// 需要使用 typename 关键字,来使编译器区分嵌套类型与嵌套值
table_driven(std::initializer_list<value_type> il) : table_driven_map_(il) {}
// 以下两个构造函数与上面的一样
// table_driven(std::initializer_list<pair<key, func>> il) {}
// table_driven(std::initializer_list<typename tb_map::value_type> il) {}
void insert(const key& first_value, func&& second_value)
{
table_driven_map_[first_value] = std::move(second_value);
}
public:
template <typename... Args>
bool handle_key(const key& first_value, Args... args)
{
auto iter = table_driven_map_.find(first_value);
if (iter != table_driven_map_.end()) {
iter->second(args...);
return true;
}
return false;
}
private:
tb_map table_driven_map_;
};
#endif
// table_map.cpp
#include <table_map.h>
void func1() {cout << "func1" << endl;}
void func2() {cout << "func2" << endl;}
void func3(int a, double b) {cout << "func3 " << a << b << endl;}
void func4(int a, double b) {cout << "func4 " << a << b << endl;}
int main()
{
int condition = 2; // key值
int val1 = 3;
double val2 = 4;
// 简单,推荐使用
table_driven<int> table1{
{1, func1}, // 使用默认func参数,调用无参函数
{2, [&]() {func3(val1,val2);}} // 使用lambda表达式作为无参形式,实际调用有参函数
};
table1.handle_key(condition);
// 复杂,不推荐使用
table_driven<int, std::function<void(int, double)>> table2{
{1, func3}, // 主动修改模板func参数为有参函数
{2, func4}
};
table2.handle_key(condition, val1, val2);
return 0;
}
参考资料:
1、C++的表驱动法
2、提高C++代码质量 - [111]用表驱动取代冗长的逻辑选择
3、模板与泛型编程知识点:编译期多态、typename标识嵌套从属类型名称