std::ranges::shift_left, std::ranges::shift_right
| Défini dans l'en-tête <algorithm>
|
||
| Signature d'appel |
||
template< std::permutable I, std::sentinel_for<I> S >
constexpr ranges::subrange<I>
shift_left( I first, S last, std::iter_difference_t<I> n );
|
(1) | (depuis C++23) |
template< ranges::forward_range R >
requires std::permutable<ranges::iterator_t<R>>
constexpr ranges::borrowed_subrange_t<R>
shift_left( R&& r, ranges::range_difference_t<R> n );
|
(2) | (depuis C++23) |
template< std::permutable I, std::sentinel_for<I> S >
constexpr ranges::subrange<I>
shift_right( I first, S last, std::iter_difference_t<I> n );
|
(3) | (depuis C++23) |
template< ranges::forward_range R >
requires std::permutable<ranges::iterator_t<R>>
constexpr ranges::borrowed_subrange_t<R>
shift_right( R&& r, ranges::range_difference_t<R> n );
|
(4) | (depuis C++23) |
Décale les éléments dans l'intervalle [first, last) ou r de n positions. Le comportement est indéfini si [first, last) n'est pas un intervalle valide.
- Si
n == 0 || n >= last - first, il n'y a aucun effet. - Si
n < 0, le comportement est indéfini. - Sinon, pour chaque entier
idans[0,last - first - n), déplace l'élément originellement à la positionfirst + n + ivers la positionfirst + i. Les déplacements sont effectués dans l'ordre croissant deien commençant par0.
- Si
n == 0 || n >= last - first, il n'y a aucun effet. - Si
n < 0, le comportement est indéfini. - Sinon, pour chaque entier
idans[0,last - first - n), déplace l'élément originellement à la positionfirst + ivers la positionfirst + n + i. SiImodélise bidirectional_iterator, alors les déplacements sont effectués dans l'ordre décroissant deien commençant parlast - first - n - 1.
r comme intervalle, comme si en utilisant ranges::begin(r) comme first et ranges::end(r) comme last.Les éléments qui se trouvent dans l'intervalle d'origine mais pas dans le nouvel intervalle sont laissés dans un état valide mais non spécifié.
Les entités de type fonction décrites sur cette page sont des objets de fonction algorithme (informellement appelés niebloids), c'est-à-dire :
- Les listes d'arguments de modèle explicites ne peuvent pas être spécifiées lors de l'appel de l'un d'eux.
- Aucun d'eux n'est visible par recherche dépendante des arguments.
- Quand l'un d'eux est trouvé par recherche non qualifiée normale comme le nom à gauche de l'opérateur d'appel de fonction, recherche dépendante des arguments est inhibée.
Paramètres
| first, last | - | la paire itérateur-sentinelle définissant la plage des éléments à décaler |
| r | - | la plage des éléments à décaler |
| n | - | le nombre de positions à décaler |
Valeur de retour
NEW_LAST
est la fin de la plage résultante et équivaut à :
-
first
+
(
last
-
first
-
n
)
, si
nest inférieur à last - first ; - first sinon.
NEW_FIRST
est le début de la plage résultante et équivaut à :
-
first
+
n
, si
nest inférieur à last - first ; - last sinon.
Complexité
Notes
ranges::shift_left
/
ranges::shift_right
ont une meilleure efficacité sur les implémentations courantes si
I
modélise
bidirectional_iterator
ou (encore mieux)
random_access_iterator
.
Les implémentations (par exemple
MSVC STL
) peuvent activer la vectorisation lorsque le type d'itérateur modélise
contiguous_iterator
et que l'échange de son type de valeur n'appelle ni fonction membre spéciale non triviale ni
ADL
-trouvée
swap
.
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_lib_shift
|
202202L
|
(C++23) |
std::ranges::shift_left
et
std::ranges::shift_right
|
Exemple
#include <algorithm> #include <iostream> #include <string> #include <type_traits> #include <vector> struct S { int value{0}; bool specified_state{true}; S(int v = 0) : value{v} {} S(S const& rhs) = default; S(S&& rhs) { *this = std::move(rhs); } S& operator=(S const& rhs) = default; S& operator=(S&& rhs) { if (this != &rhs) { value = rhs.value; specified_state = rhs.specified_state; rhs.specified_state = false; } return *this; } }; template<typename T> std::ostream& operator<<(std::ostream& os, std::vector<T> const& v) { for (const auto& s : v) { if constexpr (std::is_same_v<T, S>) s.specified_state ? os << s.value << ' ' : os << ". "; else if constexpr (std::is_same_v<T, std::string>) os << (s.empty() ? "." : s) << ' '; else os << s << ' '; } return os; } int main() { std::cout << std::left; std::vector<S> a{1, 2, 3, 4, 5, 6, 7}; std::vector<int> b{1, 2, 3, 4, 5, 6, 7}; std::vector<std::string> c{"α", "β", "γ", "δ", "ε", "ζ", "η"}; std::cout << "vector<S> \tvector<int> \tvector<string>\n"; std::cout << a << " " << b << " " << c << '\n'; std::ranges::shift_left(a, 3); std::ranges::shift_left(b, 3); std::ranges::shift_left(c, 3); std::cout << a << " " << b << " " << c << '\n'; std::ranges::shift_right(a, 2); std::ranges::shift_right(b, 2); std::ranges::shift_right(c, 2); std::cout << a << " " << b << " " << c << '\n'; std::ranges::shift_left(a, 8); // n'a aucun effet : n >= last - first std::ranges::shift_left(b, 8); // idem std::ranges::shift_left(c, 8); // idem std::cout << a << " " << b << " " << c << '\n'; // std::ranges::shift_left(a, -3); // Comportement indéfini }
Sortie possible :
vector<S> vector<int> vector<string> 1 2 3 4 5 6 7 1 2 3 4 5 6 7 α β γ δ ε ζ η 4 5 6 7 . . . 4 5 6 7 5 6 7 δ ε ζ η . . . . . 4 5 6 7 . 4 5 4 5 6 7 5 . . δ ε ζ η . . . 4 5 6 7 . 4 5 4 5 6 7 5 . . δ ε ζ η .
` qui ne doit pas être traduite - Les termes C++ (`vector`, `vector`, `vector `) ne doivent pas être traduits - Le contenu représente des données techniques et des motifs qui ne nécessitent pas de traduction
Voir aussi
(C++20) |
déplace une plage d'éléments vers un nouvel emplacement (objet fonction d'algorithme) |
(C++20) |
déplace une plage d'éléments vers un nouvel emplacement dans l'ordre inverse (objet fonction d'algorithme) |
(C++20) |
fait pivoter l'ordre des éléments dans une plage (objet fonction d'algorithme) |
(C++20)(C++20) |
décale les éléments dans une plage (modèle de fonction) |