Werden wir in der Lage sein, Container mit Ansichten in C ++ 20 zu erstellen?

10

Mit der C ++ 20-Standardversion kommen Bereiche nach C ++.

Meine Frage: Werden wir in der Lage sein, (vorhandene) Standardbibliothekscontainer mit einem beliebigen Bereich zu erstellen? Und was noch wichtiger ist, mit Entfernungsansichten?

Zum Beispiel wird dies:

#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;
}

ein gültiges Programm sein, das druckt 9 16 25?

Dies wird mit der range-v3-Bibliothek kompiliert , was das wert ist.

einpoklum
quelle
Verbunden? stackoverflow.com/questions/55950955/…
StoryTeller - Unslander Monica
Per StoryTeller: offensichtliches Duplikat von Warum unterstützt die kommende Ranges-Bibliothek die Containerinitialisierung aus einem Range nicht? - Beachten Sie jedoch, dass die Wahlentscheidung die Antwort möglicherweise noch ändert!
Davis Herring
@DavisHerring Was könnte sich ändern? P1206 wurde für 20 zunächst nicht berücksichtigt und ich glaube nicht, dass hier noch NB-Kommentare offen sind? P1391 wurde ohne den Bereichskonstruktor übernommen (trotz des irreführenden Beispiels).
Barry
@Barry: LEWG hat es in Kona weitergeleitet, aber ich glaube, ich habe den jüngsten Reflektorverkehr darüber falsch interpretiert.
Davis Herring
@DavisHerring Oh, ich habe vermisst, dass es zweimal besprochen wurde - ich habe zur 4-7-Umfrage gescrollt und dachte, das wäre das.
Barry

Antworten:

8

Meine Frage: Werden wir in der Lage sein, (vorhandene) Standardbibliothekscontainer mit einem beliebigen Bereich zu erstellen? Und was noch wichtiger ist, mit Entfernungsansichten?

Nein. Die einzige Standardbibliothekskomponente, die aus einem beliebigen Bereich konstruierbar ist, der die richtigen Kriterien erfüllt, ist std::span<T>.

Die Richtung, in die die Standardbibliothek wahrscheinlich gehen wird, ist die Richtung, in die sich range-v3 ebenfalls bewegt (beachten Sie, dass das verknüpfte Beispiel aus range-v3 zwar kompiliert wird, aber vor einer veralteten Konvertierung warnt) - Verwenden eines Hilfsprogramms , um Konvertierungen für Sie durchzuführen:

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

Einer der Gründe, nicht in die Richtung von Bereichskonstruktoren zu gehen, ist aus dem Beispiel ersichtlich, das Sie verwenden:

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

Überlegen Sie, wie unterschiedlich diese Erklärung von diesen beiden ist:

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

vwäre notwendigerweise eine, vector<transform_view<...>>die eine Single enthält transform_view, während weine vector<int>.

Darüber hinaus hilft das Hinzufügen weiterer, sorgfältig eingeschränkter Containerkonstruktoren zur Standardbibliothek ohnehin nicht den Containertypen von Drittanbietern - während eine Einrichtung wie diese ranges::toin allen Fällen einwandfrei funktioniert.

Barry
quelle
Die Anweisungen werden initialisiert vund wsehen für mich gleich aus. Vielleicht wollten Sie sich wals vector<int>. Ansonsten ist dies die richtige Antwort.
Eric Niebler
5
@ EricNiebler Genau :-) Sie sehen gleich aus. Sie sind nicht gleich.
Barry
Mein Programm wird also kompiliert, tut aber nicht das, was ich denke. OK.
Einpoklum
1
Danke, CTAD ...
TC
Können Sie bitte erklären, warum vund wsind anders? Hat dies etwas damit zu tun, wie die Ableitung von Konstruktorvorlagenargumenten funktioniert?
Johannes Schaub - Litb