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

Boost C++ Discussion :

Boost program_options plusieurs custom validator


Sujet :

Boost C++

  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut Boost program_options plusieurs custom validator
    Bonjour tout le monde,

    J'essaye de mettre en place différents Validateurs génériques en fonction de l'objet à parser.

    J'ai essayé de mettre la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<class T, typename U>
    void validate(boost::any & v, const std::vector<std::string> & values, T*, U)
    dans une classe puis faire hériter celle-ci par différentes classes d'options. Cependant, le code ne compile pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    lexical_cast.hpp:785: error: no match foroperator>>’ in ‘stream >> output’
    Pour régler ce problème (sans spécialisé la fonction validate), je ne vois que l'utilisation des namespaces: mes classes d'options devront être dans le même namespace que le custom validator.

    Connaissez-vous d'autres moyens que de passer par des namespaces?

    Merci.

  2. #2
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Tu peux faire voir ton code pour validate ?

  3. #3
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    Merci pour ta réponse,

    Voici la méthode validate (pratiquement le même que celle fournie dans la doc):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    template<class T, typename U>
    class CustomValidator
    {
    public:
    virtual void validate(boost::any & v, const std::vector<std::string> & values, T*, U)
      {
        boost::regex regexp("\\d+");
     
        boost::program_options::validators::check_first_occurrence(v);
        const std::string& s =
            boost::program_options::validators::get_single_string(values);
     
        boost::smatch match;
        if (boost::regex_match(s, match, regexp))
          {
             v = boost::any(T(boost::lexical_cast<U>(match.str())));
          }
        else
          {
            throw boost::program_options::invalid_option_value(
                "Invalid value: " + s);
          }
      }
    };
    Je ne pense pas que mon validate en lui même en soit la cause: lorsque je place cette en dehors de toute classe, celle-ci fonctionne.

  4. #4
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    J'ai trouvé une solution: il suffit de faire un template de validate qui appel le validate (ou autre fonctions...) de la classe à parser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<class T, typename U>
    void validate(boost::any & v, const std::vector<std::string> & values, T* paramPtr, U type)
    {
      T tmpPtr;
      tmpPtr.validate(v, values);
    }

  5. #5
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Bonsoir,

    Pourquoi tu surcharges validate pour tout les types ? L'intérêt de surcharger validate c'est quand la conversion lexical ne fonctionne pas pour ton type (d'où l'erreur que tu avais avec l'opérateur <<).

    La doc montre un exemple de surcharge de validate :

    1/ 4 paramètre, dont le type pour lequel tu surcharges validate en 3 et un int en 4 (il est là pour compenser un défaut de certains compilos).
    2/ fonction libre.
    3/ L'intérêt de ton "virtual" est totalement nul.

    Je ne sais pas pourquoi tu l'as mise en membre, ni même pourquoi elle devrait l'être, il n'y a priori aucun rapport entre le type de l'option et la méthode pour la parser.

    PS: Et tu as de la chance que ça compile, si tu faisais un code vraiment générique (avec basic_string), ça marcherais pas nécessairement aussi bien, tu aurais peut-être un appel ambiguë que tu n'as pas en utilisant string.

  6. #6
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    Bonjour,

    Ma classe CustomValidator a pour principal interré d'être héritée par des objets plus complexe que des objets standards. Dans mon projet, j'ai de très nombreuses options (environ 200...) qui peuvent être des vecteurs ou set d'objets déjà complexe.
    D'où l'utilisation de virtual pour pouvoir surcharger le validate pour certains cas.

  7. #7
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    1/ virtual sert à permettre la redéfinition, pas la surcharge. Dans ton cas il ne sert à rien.
    2/ En effet tu dois surcharger pour les types d'options spécifiques où un lexical_cast n'est pas suffisent.
    3/ Tu n'as pas besoin d'une classe et d'héritage pour surcharger.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void validate(boost::any & v, const std::vector<std::string> & values, un_type*, int)
    { /*stuff with values and v*/ }
     
    void validate(boost::any & v, const std::vector<std::string> & values, un autre*, int)
    { /*stuff with values and v*/ }
     
    template<class T>
    void validate(boost::any & v, const std::vector<std::string> & values, un_template<T>*, int)
    { /*stuff with values and v*/ }
     
    template<class T, class U>
    void validate(boost::any & v, const std::vector<std::string> & values, un_second<T,U>*, int)
    { /*stuff with values and v*/ }
    Voila, un exemple de 4 surcharges pour 4 "groupes" de types d'options.

    PS: Si tes types sont dans des namespaces, validate doit être dans celui-ci (c'est pas la seule solution, mais elle doit fonctionner).

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

Discussions similaires

  1. Message personnalisé et custom validator
    Par sir_gcc dans le forum JSF
    Réponses: 2
    Dernier message: 26/05/2007, 11h40
  2. Plusieurs formulaires validés par un bouton
    Par Zolex dans le forum Langage
    Réponses: 8
    Dernier message: 13/12/2006, 13h49
  3. class dialog : plusieurs custom dialog personnalisé
    Par fongus dans le forum wxWidgets
    Réponses: 2
    Dernier message: 31/10/2006, 19h24
  4. Réponses: 5
    Dernier message: 10/07/2006, 15h02
  5. plusieurs formulaire valider et prob $_POST
    Par BigBarbare dans le forum Langage
    Réponses: 7
    Dernier message: 07/04/2006, 12h09

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