在C ++ 20中,<algorithm>
标头获得了两个新算法:shift_left()
和shift_right()
。他们两个都接受任何LegacyForwardIterator。对于shift_left()
,指定了``移动i
从0
'' 开始以递增顺序执行; 对于shift_right()
,指定为“如果ForwardIt
满足LegacyBidirectionalIterator要求,则以i
从开始的降序执行移动last - first - n - 1
。”
我可以想到一种相当容易实现的方法shift_left()
:
template <typename ForwardIt>
constexpr inline ForwardIt shift_left(ForwardIt first, ForwardIt last, typename std::iterator_traits<ForwardIt>::difference_type n) {
if (n <= 0) return last;
ForwardIt it = first;
for (; n > 0; --n, ++it) {
if (it == last) return first;
}
return std::move(it, last, first);
}
如果ForwardIt
满足LegacyBidirectionalIterator的要求,我可以看到它的shift_right()
实现方式与极为相似shift_left()
。但是,目前还不清楚如何实现shift_right()
非双向正向迭代器。
我已经找到了一种算法,该算法使用atat处的空间[first, first+n)
作为元素交换的暂存空间,但似乎比shift_left()
上面的算法浪费很多:
template <typename ForwardIt>
constexpr inline ForwardIt shift_right(ForwardIt first, ForwardIt last, typename std::iterator_traits<ForwardIt>::difference_type n) {
if (n <= 0) return first;
ForwardIt it = first;
for (; n > 0; --n, ++it) {
if (it == last) return last;
}
ForwardIt ret = it;
ForwardIt ret_it = first;
for (; it != last; ++it) {
std::iter_swap(ret_it, it);
ret_it++;
if (ret_it == ret) ret_it = first;
}
return ret;
}
是否会有更好的或“预期的”实施方式shift_right()
?
@Aconcagua糟糕,是的,我将编辑问题。
—
伯纳德
std::move
代替而不是std::copy
...