如何简洁声明并初始化有限状态机的std::map类成员?
有限状态机状态转移表初始化问题解决
编译错误原因分析
你的代码出现编译错误,大概率是以下几种情况之一:
- C++版本不兼容:如果编译器未开启C11或更高版本,返回
{...}形式的列表初始化临时对象是不被支持的——列表初始化返回值是C11才引入的特性。 - 类型构造/拷贝受限:如果状态(State)或事件(Event)是自定义类型,且没有提供合适的构造函数(比如默认构造、拷贝构造),或者重载的运算符不符合要求,会导致无法用列表初始化创建键值对。
- 类型不匹配:工厂函数的返回类型与成员变量
table_的类型不一致,导致无法完成拷贝初始化。
更直接的实现方法
方法1:直接在成员初始化列表中完成初始化
不需要额外工厂函数,把所有状态转移规则集中在构造函数的初始化列表里,直观清晰:
#include <map> #include <utility> class Machine { public: using State = int; using Event = int; private: std::map<std::pair<State, Event>, State> table_; public: Machine() : table_( { {{0, 1}, 1}, // 状态0+事件1 → 状态1 {{1, 2}, 2}, // 状态1+事件2 → 状态2 {{2, 0}, 0} // 状态2+事件0 → 状态0 } ) {} };
方法2:修复工厂函数的实现(保留集中初始化的逻辑)
如果坚持用工厂函数,确保开启C++11及以上编译选项,同时把工厂函数设为static(无需访问类的非静态成员),并保证列表初始化格式正确:
#include <map> #include <utility> class Machine { public: using State = int; using Event = int; private: std::map<std::pair<State, Event>, State> table_; static std::map<std::pair<State, Event>, State> initTable() { return { {{0, 1}, 1}, {{1, 2}, 2}, {{2, 0}, 0} }; } public: Machine() : table_(initTable()) {} };
方法3:构造函数体内批量插入
如果无法在初始化列表操作,可在构造函数体内用emplace或insert批量添加转移规则:
#include <map> #include <utility> class Machine { public: using State = int; using Event = int; private: std::map<std::pair<State, Event>, State> table_; public: Machine() { // 用emplace直接构造键值对 table_.emplace(std::make_pair(0,1), 1); table_.emplace(std::make_pair(1,2), 2); table_.emplace(std::make_pair(2,0), 0); // 也可以用insert批量插入 // table_.insert({{{0,1}, 1}, {{1,2}, 2}, {{2,0}, 0}}); } };
内容的提问来源于stack exchange,提问作者centauri
相关产品推荐
相关产品推荐

