Saremo in grado di costruire container con viste in C ++ 20?


10

Gli intervalli arrivano in C ++ con la versione standard C ++ 20.

La mia domanda: saremo in grado di costruire contenitori (esistenti) di librerie standard con qualsiasi intervallo? E, soprattutto, con le viste di portata?

Ad esempio, questo:

#include <vector>
#include <iostream>
#include <ranges>

int main() {
    auto sq = [](int x) { return x * x; };
    std::vector<int> vec { 3, 4, 5 };
    std::vector<int> squares { std::ranges::views::transform(vec, sq) };
    for(auto i : squares) { std::cout << i << ' '; }
    std::cout << std::endl;
}

essere un programma valido che stampa 9 16 25?

Questo si compila con la libreria Range-V3 , per quello che vale.



Per StoryTeller: duplicato apparente di Perché la libreria Ranges in arrivo non supporta l'inizializzazione del contenitore da un intervallo? —Ma nota che la risoluzione del voto può ancora cambiare la risposta!
— Davis Herring il

@DavisHerring Cosa potrebbe cambiare? P1206 non è stato considerato per 20 per cominciare e non credo che ci siano commenti NB lasciati aperti qui? P1391 è stato adottato senza il costruttore della gamma (nonostante l'esempio fuorviante).
— Barry,

@Barry: LEWG l'ha quindi inoltrato a Kona, ma immagino di aver frainteso il recente traffico riflettore a riguardo.
— Davis Herring,

@DavisHerring Oh, mi mancava che fosse discusso due volte - sono passato al sondaggio 4-7 e ho pensato che fosse quello.
— Barry,

Risposte:


8

La mia domanda: saremo in grado di costruire contenitori (esistenti) di librerie standard con qualsiasi intervallo? E, soprattutto, con le viste di portata?

No. L'unico componente di libreria standard che è costruibile da un intervallo arbitrario che soddisfa i criteri corretti è std::span<T>.

La direzione con cui probabilmente andrà la libreria standard è quella verso cui va anche range-v3 (nota che l'esempio collegato di range-v3 viene compilato ma mette in guardia su una conversione deprecata) - usando un helper per fare conversioni per te:

std::vector<int> squares =
    std::ranges::views::transform(vec, sq) | std::ranges::to<std::vector>;

Uno dei motivi per non andare nella direzione dei costruttori di intervalli può essere visto proprio dall'esempio che stai usando:

std::vector<int> squares { std::ranges::views::transform(vec, sq) };

Considera quanto è diversa quella dichiarazione da queste due:

std::vector v { std::ranges::views::transform(vec, sq) };
std::vector w ( std::ranges::views::transform(vec, sq) );

vsarebbe necessariamente un vector<transform_view<...>>contenente un singolo transform_view, mentre wsarebbe un vector<int>.

Inoltre, l'aggiunta di altri costruttori di container attentamente vincolati alla libreria standard non aiuterà comunque i tipi di container di terze parti, mentre una struttura come ranges::tofunziona perfettamente in tutti i casi.


Le dichiarazioni inizializzano ve wsembrano uguali per me. Forse intendevi dichiarare wcome vector<int>. Altrimenti, questa è la risposta corretta.
— Eric Niebler,

5
@EricNiebler Esattamente :-) Fanno sembrare la stessa. Non sono gli stessi.
— Barry,

Quindi, il mio programma si compila ma non farà ciò che penso. Ok.
— einpoklum,

1
Grazie, CTAD ...
— TC

Puoi spiegare perché ve perché wsono diversi? Ha qualcosa a che fare con il funzionamento della deduzione dell'argomento template del costruttore?
— Johannes Schaub - litb
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.