Search code examples
c++c++14stdpass-by-referencestdvector

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


I am trying to use tuples inside a priority_queue and my tuples contain vectors. I want to be able to modify these vectors but when I delete items from a vector, it does not change the actual content. I think I am modifying the values instead of references but I am not very experienced with c++ and need some help with fixing this code:

I define my tuples like this:

   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};

and I access them like this:

      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());

I erase the first element but in the next iteration, it is still there. I tried writing to tuple using std::get<0>(elem) = block_containing_smallest_element but it also did not work.

Thanks in advance.


Solution

  • I think I am modifying the values instead of references

    That is the correct diagnosis of the problem.

    As has been pointed out in a comment, the other issue is that you cannnot modify modify elements in a std::priority_queue directly. You'll have to:

    1. Get an element by value.
    2. Modify the element.
    3. Pop the element from the queue.
    4. Push the element on to the queue.

    Use

    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);