vxWorks7下std::unordered_map插入FCS对象无法触发移动构造的问题求助
解决方案
1. 先修正FCS类定义:禁用拷贝,确保移动语义可用
因为POSIX定时器无法被拷贝,你必须显式禁用FCS的拷贝构造和拷贝赋值运算符,同时保证移动构造、移动赋值运算符可用——这是触发移动操作的核心前提。
如果你的FCS类有自定义析构函数(用于销毁定时器),C++11及以后的编译器不会自动生成移动构造/赋值,所以需要显式声明:可以用default让编译器自动生成简单的移动逻辑,也可以手动实现以精准控制资源转移。
示例代码:
class FCS { private: timer_t timer_handle_; // 存储POSIX定时器句柄,假设-1表示无效 public: // 禁用拷贝,彻底杜绝定时器拷贝行为 FCS(const FCS&) = delete; FCS& operator=(const FCS&) = delete; // 显式允许移动构造和移动赋值 // 若资源转移逻辑简单,用default让编译器自动生成 FCS(FCS&&) noexcept = default; FCS& operator=(FCS&&) noexcept = default; // 自定义析构:仅当句柄有效时销毁定时器 ~FCS() { if (timer_handle_ != -1) { timer_delete(timer_handle_); } } // 示例构造函数:根据track_id创建定时器 explicit FCS(track_id_t tid) { // 这里写初始化POSIX定时器的逻辑,给timer_handle_赋值 } };
如果需要精准控制资源转移(比如确保原对象的定时器句柄被置空,避免析构时重复销毁),可以手动实现移动构造:
FCS(FCS&& other) noexcept : timer_handle_(other.timer_handle_) { // 转移资源后,将原对象的句柄置为无效 other.timer_handle_ = -1; } FCS& operator=(FCS&& other) noexcept { if (this != &other) { // 先销毁当前对象的有效定时器 if (timer_handle_ != -1) { timer_delete(timer_handle_); } // 转移原对象的定时器资源 timer_handle_ = other.timer_handle_; other.timer_handle_ = -1; } return *this; }
2. 修正unordered_map的插入方式,确保触发移动
之前的操作未触发移动,核心是FCS缺少移动语义,同时部分插入方式会默认触发拷贝。现在推荐以下可靠的插入方式:
方式一:用emplace直接移动插入
emplace会直接在map的内存空间中构造对象,避免中间临时对象的拷贝,配合std::move将原对象转为右值,触发移动构造:
// 将f的定时器资源转移到map中,原对象f进入空状态 mHardKill.emplace(trackId, std::move(f));
如果可以直接用track_id构造FCS,还能通过分段构造完全避免临时对象:
// 直接在map中构造FCS对象,无需提前创建f mHardKill.emplace(std::piecewise_construct, std::forward_as_tuple(trackId), std::forward_as_tuple(trackId)); // 传递FCS构造所需参数
方式二:用insert配合右值pair
确保传递包含FCS右值的pair,触发移动:
mHardKill.insert(std::make_pair(trackId, std::move(f))); // 或者直接构造pair mHardKill.insert(std::pair<track_id_t, FCS>(trackId, std::move(f)));
避免使用operator[]
operator[]会在key不存在时默认构造一个FCS对象,这要求FCS有默认构造函数,之后再执行赋值操作。如果你的FCS不需要默认构造,或者想避免额外的构造开销,建议不用这种方式。
3. 为什么之前的操作没触发移动?
- 若FCS未定义移动构造/赋值,编译器会 fallback 到拷贝构造(如果拷贝构造未禁用),导致拷贝操作发生,原对象析构时销毁定时器,map中的拷贝对象持有无效句柄。
- 部分插入方式(比如直接传左值
f)本身就会触发拷贝,必须用std::move将左值转为右值,才能触发移动语义。
内容的提问来源于stack exchange,提问作者Dark Sorrow
相关产品推荐
相关产品推荐

