【问题标题】:Efficiently moving contents of std::unordered_set to std::vector有效地将 std::unordered_set 的内容移动到 std::vector
【发布时间】:2017-07-20 01:55:30
【问题描述】:

在我的代码中,我有一个std::unordered_set,我需要将数据移动到std::vector。我在获取数据时使用std::unordered_set,以确保在转换为std::vector 之前只存储唯一值。我的问题是如何最有效地将内容移动到std::vector?移动数据后我不需要std::unordered_set。我目前有以下:

std::copy(set.begin(), set.end(), std::back_inserter(vector));

【问题讨论】:

  • std::vector::reserve 肯定会有所帮助(如果您还没有这样做的话)。
  • 您的数据到底是什么?
  • 是数值。 std::vector<double>
  • 对于double,复制与移动一样有效,但您应按照 LogicStuff 的建议进行保留。另外,如果在您的情况下数据到达需要时间(例如,通过网络,来自执行异步 I/O 的大文件等)并且您实际上不需要对向量进行排序,您可以检查它是否是第一次您在尝试插入集合时已经看到了一个值,如果是这样,还插入到向量中,以便在收到最后一个输入后立即使用(尽管如果您事先知道要保留的元素数量,这效果最好) .
  • 如果两个双倍“几乎相等”,你认为它们相同吗?在某些情况下,默认散列可能不够。 stackoverflow.com/questions/14943817/…

标签: c++ c++11 vector stl copy


【解决方案1】:

在 C++17 之前,你能做的最好的事情是:

vector.insert(vector.end(), set.begin(), set.end());

set 的元素是const,所以你不能离开它们——移动只是复制。


在 C++17 之后,我们得到extract():

vector.reserve(set.size());
for (auto it = set.begin(); it != set.end(); ) {
    vector.push_back(std::move(set.extract(it++).value()));
}

尽管您的评论是您的数据是doubles,但这并不重要。

【讨论】:

  • set.extract(it++) 真的好吗?如果在extract 调用使迭代器无效之后发生增量怎么办?
  • @Dan 它不能。所有it++ 都必须在函数被评估之前发生。
  • 我觉得C++17之前也应该有储备
  • @KrvPerera 不,没关系。
  • @BRabbit27 如前所述,集合仅公开对元素的 const 访问。移动 = 复制。
猜你喜欢
  • 2018-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多