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 :

[Preprocesseur] remplacer un symbole (ou plusieurs, ici <<) par un autre (,)


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut [Preprocesseur] remplacer un symbole (ou plusieurs, ici <<) par un autre (,)
    Dans le cadre de la modernisation du code que j'entretiens et a l'aube du C++17 avec ses if constexpr et autres variadic templates, je souhaite remplacer un dans une macro par un appel a une fonction.
    Grosso modo, c'est un code tel que celui-ci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define THROW(ARGS) std::stringstream str; str << ARGS; throw std::runtime_error(str.str());
    L'idee, etant que les utilisateurs fassent un THROW("mon texte " << maValeur). Sauf que pour eviter l'inlining de la stringstream, j'aimerai bouger tout ca dans un appel de fonction et donc remplacer THROW par quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define THROW(ARGS) callThrow(REPROCESS(ARGS));
    qui remplacerai l'appel precedent par callThrow("mon texte", maValeur);

    Faisable ?

  2. #2
    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 ne suis pas certain de bien comprendre le problème que tu essayes de résoudre. Mettre des accolades autour de ton code n'est-il pas suffisant ?
    Sinon une solution simple serait de faire de callThrow une fonction template variadique, mais encore une fois, comme je n'ai pas compris ta tentative, je peux répondre à côté...
    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.

  3. #3
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    En fait, l'argument de la macro va partir dans un stringstream, mais je souhaiterai a la place que ca parte dans une fonction variadique.
    Donc de quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    THROW("du texte " << arg1 << arg2)
    la macro transforme ca en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    callThrow("du texte ", arg1, arg2)
    La raison etant (naturellement) qu'il m'est impossible de changer le code partout !

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    La macro, telle qu'elle était, permettait traiter des données de types "quelconques" grâce à l'opérateur<< de stringstream. Il est possible de s'en débarrasser mais il faudrait à la place utiliser une autre méthode capable de sérialiser les données. Ça ne ferait que déplacer le problème dans un autre objet. Ainsi la fonction callThrow("du texte ", arg1, arg2) devrait être définie par template<class...TT> [[noreturn]] void callThrow( TT&...prms ), ce qui est tout aussi lourd.

  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
    Ah, ok, je comprends un peu mieux, mais ce n'est pas évident comme truc... Par exemple, que comptes tu faire si le code contient:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    THROW(setw(10) << boolalpha << var)
    Sinon, je vois deux approches :
    - Tu crées une classe spéciale qui redéfinit un opérateur << template pour créer un tuple à partir des éléments qu'on lui passe (mon exemple est simplifié, et ne prend pas correctement en compte par exemple les forwarding references), puis qui utilise std::apply pour décomposer ce tuple lors de l'appel de ta fonction callThrow.
    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
     
    #include <memory>
    #include <tuple>
     
    std::pair<int, int> p;
     
    class Tag{};
     
    template <class Tuple, class T>
    auto operator<<(std::pair<Tag, Tuple> p, T &&t)
    {
        return std::make_pair(p.first, std::tuple_cat(p.second, std::make_tuple(t)));
    }
     
    void f()
    {
        auto seed = std::make_pair(Tag{}, std::tuple<>{});
        auto temp = seed << 12 << "Test" << 3.14;
        auto result = temp.second;
    }
    - Tu prends le taureau par les cornes et tu modifies le code source, éventuellement en écrivant un petit outil qui te permet d'automatiser un peu (ou totalement) ça...
    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
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Effectivement, je n'avais pas pense au setw() et autres... Va falloir que je reflechisse... Au moins proposer la version variadic template et progressivement changer peut-etre...

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    J'ai un besoin similaire, et avais commencé à réfléchir un truc.
    Tu peux t'en inspirer...

    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 <typename T>
    void print(std::ostream& stream, T t)
    {
          stream << t;
    }
     
    template <typename T, typename… Args>
    void print(std::ostream& stream, T t, Args… args)
    {
          stream << t ;
          print(stream, args…) ;
    }
     
    template <typename… Args>
    void ThrowIf(bool condition, Args… args)
    {
          if (condition)
          {
          std ::ostringstream message;
                print(message, args…) ;
          throw BaseException(message.str()) :
          }
    }
     
    ::Fx::Common::ErrorHandling::BaseException::ThrowIf(condition, str1, int1, str2, int2) ;

Discussions similaires

  1. [Solaris][KSH] awk : Remplacer un motif dans des noms de fichiers par un autre motif
    Par keketteboy dans le forum Shell et commandes POSIX
    Réponses: 0
    Dernier message: 12/10/2012, 15h23
  2. [WD-2007] Remplacer/Traduire des termes contenus dans un document par d'autres
    Par butcher666 dans le forum Word
    Réponses: 1
    Dernier message: 20/01/2012, 10h44
  3. Réponses: 7
    Dernier message: 03/10/2007, 17h58
  4. Réponses: 9
    Dernier message: 31/07/2007, 01h13
  5. [MS SQL] Remplacer des valeurs dans plusieurs tables
    Par salmoliv dans le forum Langage SQL
    Réponses: 3
    Dernier message: 04/10/2006, 17h31

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