You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何简洁声明并初始化有限状态机的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 03:27:25