erreur debutant itérateurs

a marqué ce sujet comme résolu.

Bonsoir à tous,

Je me suis très récemment lancé dans l’apprentissage du c++ avec le cour sur zds. J’essaye donc de résoudre cet exercice proposé, qui consiste à supprimer les espace (plus \n, \t…) au début et à la fin d’un string, mais sans succès. J’ai tenté les trois approches suivantes :

  • première tentative, je veux récupérer les itérateur correspondants aux premier et dernier caractère à conserver et m’en servir pour reconstruire un string :
auto strip(std::string str) {
    auto beg{ std::find_if_not(str.begin(), str.end(), std::isspace) };
    auto end{ std::find_if_not(str.rbegin(), str.rend(), std::isspace) };
    return std::string{ beg, end };
}

Mais le code ne compile pas et me sort une erreur l4 aucune instance du constructeur ne correspond à la liste d'arguments. Pourtant je lui passe bien deux itérateurs de string. L’erreur pourrait venir du fait que l’un des itérateur est reversed et l’autre non ? Comment faire alors ?

  • deuxième tentative, variante de la 1ère, je fais pareil mais en deux fois (une étape pour les espaces avant, et une pour ceux après) :
auto strip(std::string str) {
    auto beg{ std::find_if_not(str.begin(), str.end(), std::isspace) };
    std::string newstr{ beg, str.end() };

    auto end{ std::find_if_not(newstr.rbegin(), newstr.rend(), std::isspace) };
    return std::string{ newstr.rend() - 1, end };  // j'avais mis newstr.begin() à la place de newstr.rend() - 1,
                                                   //mais le prgm ne compilait pas, je suppose que string attend
                                                   //deux itérateurs reverse ou deux normaux et non un de chaque ?
}

Cette fois le code compile mais plante à l’exécution l6, à la création du string.

  • dernière tentative, je modifie ma chaine in place avec erase :
auto strip(std::string str) {
    auto beg{ std::find_if_not(str.begin(), str.end(), std::isspace) };
    auto end{ std::find_if_not(str.rbegin(), str.rend(), std::isspace) };

    str.erase(end, str.end());
    str.erase(str.begin(), beg);
}

Mais j’ai la même erreur qu’a ma 1ère tentative sur le 1er erase : {aucune instance de fonction surchargée ne correspond à la liste d’arguments`.

Bref j’ai l’impression que tout mes problèmes viennent du fait que je mélange les itérateurs normaux et les reversed, mais je ne sais pas vraiment comment faire autrement. La correction proposée utilise std::reversed deux fois pour ne pas avoir à utiliser d’itérateur reversed, mais est-ce la seule solution ?

+0 -0

L’erreur pourrait venir du fait que l’un des itérateur est reversed et l’autre non ?

Nicolas

Oui c’est bien ça le problème. Avec un peu de chance, ton compilateur peut te donner les raisons pour lesquelles il n’a pas pu trouver de constructor adéquat. Par exemple, clang nous donne ces infos :

error: no matching constructor for initialization of 'std::string'
note: candidate template ignored: deduced conflicting types for parameter InputIterator (normal_iterator vs. reverse_iterator).

En effet, le constructeur attend deux itérateurs du même type, ce qui n’est pas le cas actuellement. Une solution simple serait de convertir le reverse_iterator en un itérateur normal avec la fonction base().

return std::string{ beg, end.base() };
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