c++ 为什么新的range remove_* 算法移动第一个迭代器?

carvr3hs  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(126)

我正在阅读std::ranges::remove的MSVC STL实现,这时我注意到下面这行代码:

_First = _RANGES _Find_if_unchecked(_STD move(_First), _Last, _Pred, _Proj);

实际上,cppreference在其“可能的实现”中也有下面一行:

first = ranges::find_if(std::move(first), last, pred, proj);

令我困惑的是,我几乎从未见过有人移动迭代器;它们通常复制起来很便宜(或者至少应该是这样),即使这是一个复制问题,我们也可以用一个通用引用和std::forward来代替find_if的迭代器,肯定吗?
与简单地按值传递相比,强制转换为右值引用有什么优点?

gwbalxhn

gwbalxhn1#

ranges::find_if接受不一定是copyableinput_iterator(标准中的示例是basic_istream_view::iterator)。
在C++20迭代器系统中,只有模型为forward_iterator的迭代器才能保证是可复制的,所以std::move在这里是 * 必需的 *。
即使这是一个副本的问题,我们也可以使用一个通用引用,然后std::将迭代器转发到find_if。
迭代器通常按值传递。
当不能保证first迭代器是可复制的时,我们需要通过std::move将它的所有权转移给ranges::find_if,并通过它的返回重新接受它的所有权。
(尽管在您的示例中可以省略std::move,因为ranges::remove已经需要forward_iterator

相关问题