C++ 20 et Visual Studio

Problème avec std::views::take_while

Le problème exposé dans ce sujet a été résolu.

Bonjour,

J’ai récemment commencer l’étude du C++. Voulant être le plus "à la page" possible, je me suis dit qu’il serait intéressant de consulter la version bêta du tutoriel "La programmation en C++ moderne " afin d’avoir quelques notions apportées par la norme c++20.

j’en suis arrivé au chapitre II.3 : Des fonctions somme toute lambdas et j’ai un souci avec l’utilisation de std::views::take_while.

Voici le code complet, tiré directement du tuto :

#include <algorithm>
#include <iostream>
#include <ranges>
#include <vector>
 
int main()
{
    std::vector<int> const nombres { 2, 4, 8, -98, 7, 61, -54, 3 };
    auto carres_pairs = nombres
        | std::views::filter([](int n) -> bool { return n % 2 == 0; })
        | std::views::transform([](int n) -> int { return n * n; })
        | std::views::take_while([](int n) -> bool { return n < 100; });
    
    for (int nombre : carres_pairs)
    {
        std::cout << nombre << "\n";
    }

    return 0;
}

Lorsque je compile, Visual Studio me donne l’erreur suivante : C2039 - 'take_while' n’est pas membre de 'std::ranges::views’. J’ai pourtant bien configuré Visual Studio pour c++20 comme précisé dans le tuto. D’ailleurs, si je remplace std::views::take_while par std::views::filter le programme compile correctement, les views sont donc reconnus. (d’ailleurs, question annexe : quelle est la différence entre std::views::take_while et std::views::filter ?).

Le code ci-dessus compile correctement avec Wandbox, ce qui me fait dire que ça serait plus un problème lié à Visual Studio. Je précise que j’utilise Visual Studio Community 2019 - Version 16.8.5. D’autres personnes ont-elles rencontrer ce problème ?

J’en profite également pour remercier les auteurs de ce tutoriel de c++ que je trouve très complet et agréable à lire !

+0 -0

(d’ailleurs, question annexe : quelle est la différence entre std::views::take_while et std::views::filter ?)

De manière générale (et c’est aussi vrai pour d’autres langages ayant des méthodes similaires), filter garde tout élément qui correspond au filtre, quand take_while s’arrête dés qu’un élément ne correspond plus, même si d’autres éléments auraient correspondu après.

Par exemple :

std::vector<int> const nombres { 2, 4, 8, -98, 7, 61, -54, 4 };

// Contient 2, 4, 8, -98, -54, 4
auto tous_les_pairs = nombres | std::views::filter([](int n) -> bool { return n % 2 == 0; });

// Contient 2, 4, 8, -98
auto premiers_pairs = nombres | std::views::take_while([](int n) -> bool { return n % 2 == 0; });
+1 -0

@Amaury : Ah en effet, cela ne fait donc aucune différence dans le cadre de l’exemple que j’ai donné au vu de l’ordre des chiffres dans le tableau. Merci bien !

Note que take_while, du fait de sa définition, présente une différence fondamentale avec filter : il n’a pas forcément besoin de traverser l’itérable en entier. Ça veut dire notamment que tu peux manipuler avec des itérateurs infinis (comme un compteur sans borne supérieure). Je ne sais pas si C++ a ce concept (j’imagine que oui vu ses récents efforts pour introduire des abstractions diverses et variées tournant autour des itérateurs) mais c’est quelque chose qu’on retrouve notamment dans les langages fonctionnels où tous ces concepts remplacent les boucles qu’on retrouve usuellement dans les langages à style impératif. Je ne sais pas à quelle fin tu apprends C++ à présent, mais si c’est par pure curiosité envers la programmation, je t’invite fortement à aller voir des langages fonctionnels par la suite (tu as le temps bien sûr!). Ne serait-ce que pour l’ouverture d’esprit que ça apporte.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte