Di C ++ 20, <algorithm>
header mendapatkan dua algoritma baru: shift_left()
danshift_right()
. Keduanya menerima LegacyForwardIterator. Sebab shift_left()
, ditentukan bahwa "gerakan dilakukan dengan urutan i
mulai dari 0
"; untuk shift_right()
, ditentukan bahwa "jika ForwardIt
memenuhi persyaratan LegacyBidirectionalIterator, maka gerakan dilakukan dalam urutan menurun i
mulai dari last - first - n - 1
".
Saya bisa memikirkan cara yang cukup mudah untuk diterapkan 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);
}
Jika ForwardIt
memenuhi persyaratan LegacyBidirectionalIterator, saya dapat melihat bahwa shift_right()
dapat diimplementasikan dengan cara yang sangat mirip shift_left()
. Namun, tidak jelas sama sekali bagaimana seseorang dapat menerapkan shift_right()
untuk iterator forward non-bidirectional.
Saya telah menemukan sebuah algoritma yang menggunakan ruang di [first, first+n)
sebagai ruang awal untuk bertukar elemen, tetapi tampaknya sedikit lebih boros daripada algoritma untuk di shift_left()
atas:
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;
}
Apakah akan ada cara implementasi yang lebih baik atau "dimaksudkan" shift_right()
?
std::move
daripadastd::copy
...