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.