我正在阅读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
的迭代器,肯定吗?
与简单地按值传递相比,强制转换为右值引用有什么优点?
1条答案
按热度按时间gwbalxhn1#
ranges::find_if
接受不一定是copyable
的input_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
)