std::ranges:: to
|
Défini dans l'en-tête
<ranges>
|
||
|
template
<
class
C,
ranges::
input_range
R,
class
...
Args
>
requires
(
!
ranges::
view
<
C
>
)
|
(1) | (depuis C++23) |
|
template
<
template
<
class
...
>
class
C,
ranges::
input_range
R,
class
...
Args
>
|
(2) | (depuis C++23) |
|
template
<
class
C,
class
...
Args
>
requires
(
!
ranges::
view
<
C
>
)
|
(3) | (depuis C++23) |
|
template
<
template
<
class
...
>
class
C,
class
...
Args
>
constexpr /*adaptateur de plage de fermeture*/ to ( Args && ... args ) ; |
(4) | (depuis C++23) |
|
Modèles d'assistance
|
||
|
template
<
class
Container
>
constexpr
bool
/*conteneur-réservable*/
=
|
(5) | ( exposition uniquement* ) |
|
template
<
class
Container,
class
Reference
>
constexpr
bool
/*ajoutable-au-conteneur*/
=
|
(6) | ( exposition uniquement* ) |
|
template
<
class
Reference,
class
C
>
constexpr auto /*container-appender*/ ( C & c ) ; |
(7) | ( exposition uniquement* ) |
|
template
<
class
R,
class
T
>
concept
/*container-compatible-range*/
=
|
(8) | ( exposition uniquement* ) |
Les surcharges de la fonction de conversion de plage construisent un nouvel objet non-vue à partir d'une plage source comme premier argument en appelant un constructeur prenant une plage, un
std::from_range_t
constructeur de plage étiqueté, un constructeur prenant une paire itérateur-sentinelle, ou en insérant en arrière chaque élément de la plage source dans l'objet construit par les arguments.
C
à partir des éléments de
r
de la manière suivante :
C
ne satisfait pas
input_range
ou
std::
convertible_to
<
ranges::
range_reference_t
<
R
>
,
ranges::
range_value_t
<
C
>>
est
true
:
C
à partir de la plage source
std::
forward
<
R
>
(
r
)
et des autres arguments fonctionnels
std::
forward
<
Args
>
(
args
)
...
si
std::
constructible_from
<
C, R, Args...
>
est
true
.
C
à partir du tag de désambiguïsation supplémentaire
std::
from_range
, la plage source
std::
forward
<
R
>
(
r
)
et les autres arguments fonctionnels
std::
forward
<
Args
>
(
args
)
...
si
std::
constructible_from
<
C,
std::
from_range_t
, R, Args...
>
est
true
.
C
à partir de la paire itérateur-sentinelle (
ranges::
begin
(
r
)
comme itérateur et
ranges::
end
(
r
)
comme sentinelle, où l'itérateur et la sentinelle ont le même type. En d'autres termes, la plage source doit être une plage commune), et les autres arguments de fonction
std::
forward
<
Args
>
(
args
)
...
si toutes les conditions suivantes sont
true
:
- ranges:: common_range < R >
- Si std:: iterator_traits < ranges:: iterator_t < R >> :: iterator_category est valide et désigne un type qui satisfait std:: derived_from < std:: input_iterator_tag >
- std:: constructible_from < C, ranges:: iterator_t < R > , ranges:: sentinel_t < R > , Args... >
C
à partir des autres arguments de la fonction
std::
forward
<
Args
>
(
args
)
...
avec l'appel équivalent suivant après la construction :
|
if
constexpr
(
ranges::
sized_range
<
R
>
&&
/*reservable-container*/
<
C
>
)
|
(jusqu'en C++26) |
|
if
constexpr
(
ranges
::
approximately_sized_range
<
R
>
|
(depuis C++26) |
Si
R
satisfait
sized_range
(jusqu'en C++26)
approximately_sized_range
(depuis C++26)
et
C
satisfait
reservable-container
, l'objet construit
c
de type
C
peut réserver du stockage avec la taille de stockage initiale
ranges::
size
(
r
)
(jusqu'en C++26)
ranges
::
reserve_hint
(
r
)
(depuis C++26)
pour éviter des allocations supplémentaires lors de l'insertion de nouveaux éléments. Chaque élément de
r
est ajouté à
c
.
Les opérations ci-dessus sont valides si les deux conditions suivantes sont true :
- std:: constructible_from < C, Args... >
-
container-appendable< C, ranges:: range_reference_t < R >>
to
<
C
>
(
ranges::
ref_view
(
r
)
|
views::
transform
(
[
]
(
auto
&&
elem
)
{
return
to
<
ranges::
range_value_t
<
C
>>
(
std::
forward
<
decltype
(
elem
)
>
(
elem
)
)
;
}
)
,
std::
forward
<
Args
>
(
args
)
...
)
Ce qui permet les constructions de plages imbriquées à l'intérieur de la plage si
ranges::
input_range
<
ranges::
range_reference_t
<
C
>>
est
true
.
Soit /*input-iterator*/ un type d'exposition uniquement qui satisfait LegacyInputIterator :
|
struct
/*itérateur-entrée*/
{
|
( exposition uniquement* ) | |
Soit /*DEDUCE-EXPR*/ défini comme suit :
- C ( std:: declval < R > ( ) , std:: declval < Args > ( ) ... ) , si cette expression est valide.
-
Sinon,
C
(
std::
from_range
,
std::
declval
<
R
>
(
)
,
std:: declval < Args > ( ) ... ) , si cette expression est valide. -
Sinon,
C
(
std::
declval
<
/*input-iterator*/
>
(
)
,
std:: declval < /*input-iterator*/ > ( ) ,
std:: declval < Args > ( ) ... ) , si cette expression est valide. - Sinon, le programme est mal formé.
( std:: forward < R > ( r ) , std:: forward < Args > ( args ) ... ) .
Reference
peut être ajouté à
Container
via un appel de fonction membre
emplace_back
,
push_back
,
emplace
ou
insert
.
return
[
&
c
]
<
class
Reference
>
(
Reference
&&
ref
)
{
if
constexpr
(
requires
{
c.
emplace_back
(
std::
declval
<
Reference
>
(
)
)
;
}
)
c.
emplace_back
(
std::
forward
<
Reference
>
(
ref
)
)
;
else
if
constexpr
(
requires
{
c.
push_back
(
std::
declval
<
Reference
>
(
)
)
;
}
)
c.
push_back
(
std::
forward
<
Reference
>
(
ref
)
)
;
else
if
constexpr
(
requires
{
c.
emplace
(
c.
end
(
)
,
std::
declval
<
Reference
>
(
)
)
;
}
)
c.
emplace
(
c.
end
(
)
,
std::
forward
<
Reference
>
(
ref
)
)
;
else
c.
insert
(
c.
end
(
)
,
std::
forward
<
Reference
>
(
ref
)
)
;
}
;
R
dont le type de référence de plage doit être convertible en
T
.
Table des matières |
Paramètres
| r | - | un objet de plage source |
| args | - | liste des arguments pour ( 1,2 ) construire une plage ou ( 3,4 ) lier aux derniers paramètres de l'objet de fermeture d'adaptateur de plage |
| Exigences de type | ||
-
C
doit être un type de classe non qualifié cv
(
1,3
)
|
||
Valeur de retour
ranges::to type de retour
Objets membres
L'objet retourné se comporte comme s'il n'avait pas d'objet cible, et un objet std::tuple tup construit avec std:: tuple < std:: decay_t < Args > ... > ( std:: forward < Args > ( args ) ... ) , sauf que le comportement d'affectation de l'objet retourné n'est pas spécifié et les noms sont uniquement à titre d'exposition.
Constructeurs
Le type de retour de
ranges::to
(
3,4
)
se comporte comme si ses constructeurs de copie/déplacement effectuaient une copie/déplacement membre par membre. Il est
CopyConstructible
si tous ses objets membres (spécifiés ci-dessus) sont
CopyConstructible
, et est
MoveConstructible
sinon.
Fonction membre
operator()
Étant donné un objet
G
obtenu d'un appel antérieur à
range
::
to
<
/* see below */
>
(
args...
)
, lorsqu'une glvalue
g
désignant
G
est invoquée dans une expression d'appel de fonction
g
(
r
)
, un appel de l'objet stocké a lieu, comme par
- ranges :: to < /* see below */ > ( r, std :: get < Ns > ( g. tup ) ... ) , où
-
-
r
est un objet plage source qui doit satisfaire
input_range. - Ns est un pack d'entiers 0 , 1 , ..., ( sizeof... ( Args ) - 1 ) .
- g est une lvalue dans l'expression d'appel si c'est une lvalue dans l'expression d'appel, et est une rvalue sinon. Ainsi std :: move ( g ) ( r ) peut déplacer les arguments liés dans l'appel, où g ( r ) copierait.
-
L'argument template spécifié est
(
3
)
Cou ( 4 ) le type déduit d'un template de classeCqui ne doit pas satisfaireview.
-
r
est un objet plage source qui doit satisfaire
Le programme est mal formé si g a un type qualifié volatile.
Exceptions
Ne lance que si la construction d'un objet non-vue lève une exception.
Notes
L'insertion d'éléments dans le conteneur peut impliquer une copie qui peut être moins efficace que le déplacement car des références lvalue sont produites lors de l'appel d'indirection. Les utilisateurs peuvent opter pour utiliser views:: as_rvalue pour adapter la plage afin que leurs éléments produisent toujours une référence rvalue lors de l'appel d'indirection, ce qui implique un déplacement.
Les parenthèses sont obligatoires lors de l'utilisation de la syntaxe de pipe.
auto vec = r | std::ranges::to<std::vector>; // Erreur auto vec = r | std::ranges::to<std::vector>(); // Correct
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_lib_ranges_to_container
|
202202L
|
(C++23) |
std::ranges::to
|
__cpp_lib_ranges_reserve_hint
|
202502L
|
(C++26) |
ranges::approximately_sized_range
,
ranges::reserve_hint
, et
modifications
de
std::ranges::to
|
Exemple
Un lien de prévisualisation : Compiler Explorer
#include <boost/container/devector.hpp> #include <concepts> #include <initializer_list> #include <list> #include <print> #include <ranges> #include <regex> #include <string> #include <vector> #ifndef __cpp_lib_format_ranges #include <format> #include <sstream> auto print_aid(const auto& v) { std::ostringstream out; out << '['; for (int n{}; const auto& e : v) out << (n++ ? ", " : "") << e; out << ']'; return out; } template<typename T> struct std::formatter<std::vector<T>, char> { template<class ParseContext> constexpr ParseContext::iterator parse(ParseContext& ctx) { return ctx.begin(); } template<class FmtContext> FmtContext::iterator format(auto const& s, FmtContext& ctx) const { auto out{print_aid(s)}; return std::ranges::copy(std::move(out).str(), ctx.out()).out; } }; template<typename T> struct std::formatter<std::list<T>, char> { template<class ParseContext> constexpr ParseContext::iterator parse(ParseContext& ctx) { return ctx.begin(); } template<class FmtContext> FmtContext::iterator format(auto const& s, FmtContext& ctx) const { auto out{print_aid(s)}; return std::ranges::copy(std::move(out).str(), ctx.out()).out; } }; #endif int main() { auto vec = std::views::iota(1, 5) | std::views::transform([](int v){ return v * 2; }) | std::ranges::à<std::vector>(); static_assert(std::same_as<decltype(vec), std::vector<int>>); std::println("{}", vec); auto list = vec | std::views::take(3) | std::ranges::à<std::list<double>>(); std::println("{}", list); } void ctor_demos() { // 1.a.1) Initialisation directe { char array[]{'a', 'b', '\0', 'c'}; // Le type d'argument est convertible en type de valeur de résultat : auto str_to = std::ranges::à<std::string>(array); // Équivalent à std::string str(array); // Le type de résultat n'est pas une plage d'entrée : auto re_to = std::ranges::à<std::regex>(array); // Équivalent à std::regex re(array); } // 1.a.2) constructeur from_range { auto list = {'a', 'b', '\0', 'c'}; // Le type d'argument est convertible en type de valeur de résultat : auto str_to = std::ranges::à<std::string>(list); // Équivalent à // std::string str(std::from_range, list); // Le type de résultat n'est pas une plage d'entrée : [[maybe_unused]] auto pair_to = std::ranges::à<std::pair<std::from_range_t, bool>>(true); // Équivalent à std::pair<std::from_range_t, bool> pair(std::from_range, true); } // 1.a.3) constructeur avec paire d'itérateurs { auto list = {'a', 'b', '\0', 'c'}; // Le type d'argument est convertible en type de valeur de résultat : auto devector_to = std::ranges::à<boost::container::devector<char>>(list); // Équivalent à boost::container::devector<char> devector(std::ranges::begin(list), std::ranges::end(list)); // Le type de résultat n'est pas une plage d'entrée : std::regex re; auto it_to = std::ranges::à<std::cregex_iterator>(list, re); // Équivalent à std::cregex_iterator it(std::ranges::begin(list), std::ranges::end(list), re); } }
Sortie :
[2, 4, 6, 8] [2, 4, 6]
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Applicable à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 3984 | C++23 |
la branche de construction imbriquée de
ranges::to
rendait le programme
mal formé si
R&
ne modélise pas
viewable_range
|
rendu bien formé |
| LWG 4016 | C++23 |
la branche d'insertion de conteneur de
ranges::to
impliquait l'utilisation d'itérateurs d'insertion
|
remplacée par l'ajout direct
d'éléments au conteneur |
Références
- Norme C++23 (ISO/CEI 14882:2024) :
-
- 26.5.7 Conversions de plages [range.utility.conv]