传递矢量作为对 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
中的修改元素。你必须:
- 按值获取元素。
- 修改元素。
- 从队列中弹出元素。
- 将元素推入队列。
使用
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
我正在尝试在 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
中的修改元素。你必须:
- 按值获取元素。
- 修改元素。
- 从队列中弹出元素。
- 将元素推入队列。
使用
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