C ++ 20では、<algorithm>
ヘッダは、2つの新しいアルゴリズムを獲得: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()
非双方向の順方向反復子をどのように実装するかは、まったく明確ではありません。
[first, first+n)
要素のスワッピングにスクラッチスペースとしてスペースatを使用するアルゴリズムを見つけましたが、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()
か?
std::move
代わりのをstd::copy
...