传递矢量作为对 Std::Tuple 的引用并修改它

Passing Vector as a Reference to Std::Tuple and Modifying It

我正在尝试在 priority_queue 中使用元组,我的元组包含向量。我希望能够修改这些向量,但是当我从向量中删除项目时,它不会更改实际内容。我想我正在修改值而不是引用,但我对 C++ 不是很有经验,需要一些帮助来修复此代码:

我这样定义我的元组:

   using tuple_type = std::tuple<std::vector<uint64_t>, File*, size_t>;
   auto comparator = [](tuple_type const &a, tuple_type const &b) {
      return std::get<0>(a).front()> std::get<0>(b).front();
   };

   std::priority_queue<tuple_type, std::vector<tuple_type>, decltype(comparator)> pq{comparator};

我这样访问它们:

      auto elem = pq.top();
      auto *file = std::get<1>(elem);
      auto block_containing_smallest_element = std::get<0>(elem);
      to_write.push_back(block_containing_smallest_element.front());
      block_containing_smallest_element.erase(block_containing_smallest_element.begin());

我删除了第一个元素,但在下一次迭代中,它仍然存在。我尝试使用 std::get<0>(elem) = block_containing_smallest_element 写入元组,但它也没有用。

提前致谢。

I think I am modifying the values instead of references

这是对问题的正确诊断。

正如评论中指出的那样,另一个问题是您不能直接修改 std::priority_queue 中的修改元素。你必须:

  1. 按值获取元素。
  2. 修改元素。
  3. 从队列中弹出元素。
  4. 将元素推入队列。

使用

auto elem = pq.top();
auto *file = std::get<1>(elem);
auto& block_containing_smallest_element = std::get<0>(elem);
to_write.push_back(block_containing_smallest_element.front());
block_containing_smallest_element.erase(block_containing_smallest_element.begin());
pq.pop();
pq.push(elem);

原因很清楚,因为实际元素在优先级队列中,而不是在自动变量中。如果您看到这行代码:

auto block_containing_smallest_element = std::get<0>(elem);

在这里,创建了一个类型为 auto 的新变量,以便 c++ 自行确定类型,但是当您在最后一行删除它时,

block_containing_smallest_element.erase(block_containing_smallest_element.begin()); 

这里你只是从一个变量中删除一个变量!!,这里你需要给出:

auto& elem = pq.top();
auto *file = std::get<1>(elem);
auto& block_containing_smallest_element = std::get<0>(elem);

还要记住它是一个 PIRORITY QUEUE,因此即使您从变量中删除一个元素,它也会影响实际的元素,因为它没有指向原始 PQ