当类包含boost::container::flat_set时,复制对象时出错

Error copying objects when class contains boost::container::flat_set

本文关键字:复制 出错 对象 set flat 包含 boost container      更新时间:2023-10-16

在(false?)认为boost::container::flat_setstd::set的替代品的情况下,我将set替换为flat_set,只要我希望元素数量少,并且搜索性能比插入更关键。

在后来的阶段,我被一个令人困惑的编译错误难住了,我最终将其追溯到使用flat_set作为类成员。

例如:

class Room {
private:
boost::container::flat_set<int> v;
};

下面的代码不会编译,但如果我用std::set替换flat_set,它就可以正常工作。

Room a;
Room b = Room(); // Example 1. Compiles OK
a = b;           // Example 2. Compiles OK
a = Room();      // Example 3. Eeeek! Compile fails on this line

我看到的编译错误是:

错误:"a=Room()"中的"operator="不匹配注:候选人为:注意:房间和房间::operator=(房间和)注意:参数1没有从"Room"到"Room&"的已知转换

我的问题是:

  1. 这是预期的错误吗?如果是,那么我该如何解决它
  2. 示例代码中的三个语句有何不同,为什么只有最后一个语句失败
  3. 为什么编译器抱怨Room的赋值运算符而不是flat_setflat_set的使用是否影响了为类生成的默认运算符

完整的样本程序:

#include <boost/container/flat_set.hpp>
class Room {
private:
boost::container::flat_set<int> v;
};
int main(int argc, char *argv[]) {
Room a;
Room b = Room();
a = b;
a = Room();  // compilation fails here
return 0;
};

这是Boost.move执行的移动模拟的已知限制。您可以在此处找到有关它的更多信息:http://www.boost.org/doc/libs/1_52_0/doc/html/move/emulation_limitations.html#move.emulation_limitations.assignment_operator

免责声明: 我是OP;我已经接受了K-ballo的回答,因为它导致了最终的解决方案,我发布这篇文章是为了用一些细节来补充这个帖子

正如在接受的答案中所提到的,这确实是对使用BOOST_COPYABLE_AND_MOVABLE宏的类的已知限制(这适用于boost::container中的许多类,包括flat_setflat_map)。

为了克服这一点,我为类定义了一个赋值运算符,该运算符采用常量引用参数。例如,在quesiton中的示例Room类的情况下,它将沿着以下行:

class Room {
private:
boost::container::flat_set<int> v;
public:
Room& operator=(const Room& source) {
v = source.v;
return *this;
}
};