Serons-nous capables de construire des conteneurs avec des vues en C ++ 20?

10

Les gammes arrivent en C ++ avec la version standard C ++ 20.

Ma question: serons-nous en mesure de construire des conteneurs de bibliothèque standard (existants) avec n'importe quelle gamme? Et plus important encore, avec des vues de portée?

Par exemple, cela va-t-il:

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

être un programme valide qui imprime 9 16 25?

Cela se compile avec la bibliothèque range-v3 , pour ce que ça vaut.

einpoklum
la source
En relation? stackoverflow.com/questions/55950955/…
StoryTeller - Unslander Monica
Par StoryTeller: double apparent de Pourquoi la prochaine bibliothèque Ranges ne prend-elle pas en charge l'initialisation des conteneurs à partir d'une plage? - mais notez que la résolution du scrutin peut encore changer la réponse!
Davis Herring
@DavisHerring Qu'est-ce qui pourrait changer? P1206 n'a pas été envisagé pour 20 pour commencer et je ne pense pas qu'il y ait des commentaires du NB laissés ouverts ici? P1391 a été adopté sans le constructeur de la gamme (malgré l'exemple trompeur).
Barry
@Barry: LEWG l'a donc transmis à Kona, mais je suppose que j'ai mal interprété le trafic récent des réflecteurs à ce sujet.
Davis Herring
@DavisHerring Oh, j'ai raté que cela ait été discuté deux fois - j'ai défilé jusqu'au sondage 4-7 et j'ai pensé que c'était ça.
Barry

Réponses:

8

Ma question: serons-nous en mesure de construire des conteneurs de bibliothèque standard (existants) avec n'importe quelle gamme? Et plus important encore, avec des vues de portée?

Non. Le seul composant de bibliothèque standard pouvant être construit à partir d'une plage arbitraire répondant aux critères appropriés est std::span<T>.

La direction dans laquelle la bibliothèque standard ira probablement est celle vers laquelle range-v3 va également (notez que l'exemple lié de range-v3 se compile mais met en garde contre une conversion obsolète) - en utilisant un assistant pour effectuer des conversions pour vous:

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

Une des raisons de ne pas aller dans le sens des constructeurs de plage peut être vue dans l'exemple même que vous utilisez:

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

Considérez à quel point cette déclaration est différente de ces deux:

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

vserait nécessairement un vector<transform_view<...>>contenant un seul transform_view, tandis que wserait un vector<int>.

De plus, l'ajout de constructeurs de conteneurs plus restreints avec soin à la bibliothèque standard ne va de toute façon pas aider les types de conteneurs tiers - alors qu'une installation comme ranges::tofonctionne parfaitement dans tous les cas.

Barry
la source
Les déclarations s'initialisent vet wme semblent identiques. Peut-être que vous vouliez déclarer wcomme vector<int>. Sinon, c'est la bonne réponse.
Eric Niebler
5
@EricNiebler Exactement :-) Ils se ressemblent . Ils ne sont pas les mêmes.
Barry
Donc, mon programme compile mais ne fera pas ce que je pense qu'il fait. D'accord.
einpoklum
1
Merci, CTAD ...
TC
Pouvez-vous expliquer pourquoi vet wsont différents? Cela a-t-il quelque chose à voir avec le fonctionnement de la déduction des arguments du modèle constructeur?
Johannes Schaub - litb