使用std::move_iterator实现约瑟夫环排列时erase报错,如何解决?
约瑟夫环排列问题:std::move_iterator 适配 erase 的解决方案
问题核心
编译报错的原因是:cur_pos是std::move_iterator类型,而std::list::erase仅接受容器的原生迭代器(即std::list<T>::iterator),不支持包装后的move_iterator。
解决方法
调用std::move_iterator的base()成员函数,取出其底层封装的原生迭代器,再传递给erase即可。
修改后的代码
template <typename RandomIt> void MakeJosephusPermutation(RandomIt first, RandomIt last, uint32_t step_size) { list<typename RandomIt::value_type> pool; for (auto it = make_move_iterator(first); it != make_move_iterator(last); ++it) { pool.push_back(*it); } auto cur_pos = make_move_iterator(pool.begin()); while (!pool.empty()) { *(first++) = *cur_pos; if (pool.size() == 1) { break; } const auto next_pos = LoopIterator(pool, next(cur_pos)); // 关键修改:调用base()取出原生迭代器 pool.erase(cur_pos.base()); cur_pos = next_pos; for (uint32_t step_index = 1; step_index < step_size; ++step_index) { cur_pos = LoopIterator(pool, next(cur_pos)); } } }
补充说明
std::move_iterator的本质是对原生迭代器的包装,仅在解引用时触发移动语义,其base()方法可以还原出原始的迭代器。- 如果
LoopIterator函数的参数期望是原生迭代器,你还需要对next(cur_pos)调用base(),即LoopIterator(pool, next(cur_pos).base()),具体取决于LoopIterator的实现逻辑。
内容的提问来源于stack exchange,提问作者Pavel Sh
相关产品推荐
相关产品推荐

