C ++ 20'de, <algorithm>
başlık iki yeni algoritma kazanır: shift_left()
veshift_right()
. Her ikisi de herhangi bir LegacyForwardIterator'ı kabul eder. Çünkü shift_left()
, "hamlelerin i
başlangıçtan itibaren artan sırayla gerçekleştirildiği 0
" belirtilir; için shift_right()
, " ForwardIt
LegacyBidirectionalIterator gereksinimlerini karşılıyorsa, hareketlerin i
başlangıçtan itibaren azalan sırada gerçekleştirildiği last - first - n - 1
" belirtilir.
Uygulamanın oldukça kolay bir yolunu düşünebilirim 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);
}
Eğer ForwardIt
LegacyBidirectionalIterator gereksinimlerini karşılar, bunu görebiliyorum shift_right()
olarak çok benzer bir şekilde uygulanabilir shift_left()
. Ancak, shift_right()
çift yönlü olmayan ileriye doğru yineleyiciler için nasıl uygulanabileceği açık değildir .
Ben [first, first+n)
öğeleri takas için sıfırdan boşluk olarak alan kullanan bir algoritma anladım , ama shift_left()
yukarıdaki algoritma biraz daha israf görünüyor :
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;
}
Uygulamanın daha iyi veya "amaçlanan" bir yolu var shift_right()
mı?
std::move
tercih ederstd::copy
...