IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Ecriture générique pour manipuler des (w)string


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut Ecriture générique pour manipuler des (w)string
    J'hésite entre deux écritures pour un même résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<typename C, typename Tr, typename Al>
    void all_trim(std::basic_string<C, Tr, Al> & s, C const *cs)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<typename S>
    void all_trim(S & s, S::value_type const *cs)
    Jusqu'à présent j'avais tendance à utiliser la première écriture pour mes petites fonctions de manipulations de (w)string, mais je suis en train de revoir ma copie pour utiliser la deuxième. C'est plus court et plus simple finalement.
    Et ça me permet d'écrire ceci par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<typename S>
    S trim(S && s, S::value_type const *cs)
    {
    	S ms(std::forward<S>(s));
    	all_trim(ms, cs);
    	return ms;
    }
    Des avis ?
    Merci.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Si tu ne comptes utiliser que des std::(w)string, autant aller au plus simple à écrire et comprendre imo.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Je croyais tout bon, et puis patatras, ceci ne compile pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<typename S>
    S trim(S && s, S::value_type const *cs)
    {
    	S ms(std::forward<S>(s));
    	all_trim(ms, cs);
    	return ms;
    }
    Visual Studio 2015 me donne ces erreurs:
    error C2672: 'trim': no matching overloaded function found_
    error C2893: Failed to specialize function template 'S trim(S &&,const S::value_type *)'_

    Je dois faire comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<typename S, typename C>
    S trim(S && s, C const *cs)
    {
    	S ms(std::forward<S>(s));
    	all_trim(ms, cs);
    	return ms;
    }
    Mais je ne comprends pas trop pourquoi... (bien que ça ne me dérange pas, mais comprendre c'est toujours bon )

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Comme tu utilises std::wstring et std::string, tu fournis en réalité une spécialisation de std::basic_string. Si bien que S::value_type n'est en réalité que le typedef que l'on trouve dans std::basic_string qui correspond au type de caractères à utiliser.

    Or, ce typedef est dépendant de la spécialisation de std::basic_string que tu utilise (et qui te sert de paramètre template), tu devrais donc -- si je ne m'abuse -- clairement spécifier qu'il est dépéndant du paramètre template, sous une forme (non testée) qui serait proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<typename S>
    S trim(S && s, typename S::value_type const *cs)
    {
    	S ms(std::forward<S>(s));
    	all_trim(ms, cs);
    	return ms;
    }
    (d'ailleurs il y a peut-etre bien un typedef plus intéressant à utiliser comme const_pointer)

    Une autre solution pourrait être (histoire de t'assurer que C fait bien partie de la spécialisation de std::basic_string représentée par S) de fournir une valeur par défaut pour C, sous la forme de (toujours non testé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<typename S, typename C= typename S::value_type> //  je préférerais vraiment const_pointer à value_type
    S trim(S && s, C const *cs)
    {
    	S ms(std::forward<S>(s));
    	all_trim(ms, cs);
    	return ms;
    }
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Je préfère ta seconde écriture, en plus d'être plus simple, elle fonctionnera avec plus de types semblables à des strings que std::basic_string. La première n'a d'intérêt à mon sens que si tu veux jouer avec les paramètres, par exemple convertir ta std::basic_string<C, Tr, Al> en std::basic_string<C, AnotherCharTrait, Al>.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Merci pour vos réponses !
    J'y vois un peu plus clair

    Après d'autres petits tests, la présence ou non du mot clé typename ne change rien, la même erreur de compilation survient.
    C'est la présence de l'opérateur && qui semble perturber le compilateur.

    Je reprends ici le code (adapté à juste titre comme proposé par koala01)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<typename S>
    inline S trim(S && s, typename S::const_pointer cs)
    {
    	S ms(std::forward<S>(s));
    	all_trim(ms, cs);
    	return ms;
    }
    Ce code n'est accepté que si le paramètre "s" est une rvalue.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<typename S, typename Cptr = typename S::const_pointer>
    inline S trim(S && s, Cptr cs)
    {
    	S ms(std::forward<S>(s));
    	all_trim(ms, cs);
    	return ms;
    }
    Celui-ci semble toujours être accepté, lvalue ou rvalue pour le paramètre "s".

    Moi qui croyais avoir tout compris, voici une petite zone d'ombre (pas bien grave ).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Bibliotheque pour manipuler des buffer string
    Par Tail dans le forum Bibliothèque standard
    Réponses: 1
    Dernier message: 09/08/2009, 20h57
  2. Meilleure methode pour manipuler des images
    Par etranger dans le forum Modules
    Réponses: 2
    Dernier message: 16/02/2007, 13h06
  3. API pour manipuler des RPM
    Par pcery dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 07/08/2006, 14h44
  4. Quel langage pour manipuler des entiers très longs ?
    Par mis_dj dans le forum Langages de programmation
    Réponses: 8
    Dernier message: 10/05/2006, 21h12
  5. Delphi 2005 pour manipuler des formulaires MS-Access ??
    Par Mustard007 dans le forum Bases de données
    Réponses: 4
    Dernier message: 18/10/2005, 21h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo