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 :

Comment créer son propre "cout" avec un "endl" ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut Comment créer son propre "cout" avec un "endl" ?
    Bonjour à tous,

    j'ai une classe qui surcharge l'opérateur << pour permettre la sortie formatée vers un ostream.

    Je veux que l'utilisateur de ma classe puisse déclarer son propre ostream-like avec une sortie formatée à lui.
    Tout marche comme je veux sauf pour le retour à la ligne avec endl.
    Voici un petit bout de code (ultra simplifié) qui illustre mon cas:
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    struct Point // ma classe
        {
        int x,y ;
     
        // avec sa surcharge de l'opérateur de sortie formatée
        template <typename output>
        friend output & operator<< ( output & o , const Point & t ) ;
        } ;
     
    // implémentation de l'opérateur de sortie formatée
    template <typename output> output & operator<< ( output & o , const Point & t )
        {
        o << "(" << t.x << "," << t.y << ")" ;
        // o << output::endl ; // ne compile pas avec o == std::cout car endl n'est pas membre de std::ostream
        return o ;
        }
     
    // le ostream-like de l'utilisateur
    struct my_ostream
        {
        my_ostream & operator<< ( int x )                       { printf("int    : %d\n",x ) ; return *this ;}
        my_ostream & operator<< ( const char * s )              { printf("string : \"%s\"\n",s ) ; return *this ;}
        my_ostream & operator<< ( my_ostream&(*f)(my_ostream&)) { return f( *this ) ;}
        // le "endl" de my_ostream a la même signature que celui de std :
        static my_ostream & endl ( my_ostream & o )             { printf("end of line\n") ; return o ;}
        } ;
     
    void test_output2 ()
        {
        Point p = { 12,13 } ;
        my_ostream my_cout ;
        my_cout << p ;
        std::cout << p ; // si je commente cet appel, le "o << output::endl" du dessus compile bien.
        }
    Quelqu'un saurait-il comment faire (proprement) ce genre de truc ?

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    188
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 188
    Par défaut
    Bonjour,

    Peut être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static const char endl = '\n';
    Après tout c'est juste pour signaler une fin de ligne

  3. #3
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    en fait le endl fait un flush aussi

  4. #4
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    En fait, ce que je voudrais, c'est pouvoir faire ces 2 appels et que ça marche !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my_cout << p ;   // utilise un ostream perso
    std::cout << p ; // utilise le ostream des stl
    Or, dans mon exemple, l'appel "<< endl" dans ma surcharge de l'opérateur << ne compile pas pour la 2eme ligne.

  5. #5
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    output est un type et en gros tu es en train de demander à ton compilateur de compiler un appel std::ostream::std::endl, ce qui n'a pas de sens, std::endl n'étant absolument pas membre de std::ostream
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  6. #6
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    La maniere habituelle de faire son "ostream like" est de definir un streambuf -- apres quoi tu n'as plus de probleme.

  7. #7
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    std::endl n'étant absolument pas membre de std::ostream
    Bé oui, je sais bien, d'où ma question...
    Mais merci pour ce lien précieux ! de longues heures de lecture en perspectives... toutefois j'ai peur de ne pas y trouver ma réponse.

    Pour mon machin, la solution de atttchoum est celle vers laquelle je me dirigeais... ça donne un truc comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    struct my_ostream
        {
        // j'ajoute cette méthode qui va traduire les manipulateurs
        template <class c, class t>
        my_ostream & operator<< ( std::basic_ostream<c,t>&(*f)(std::basic_ostream<c,t>&)) 
            { 
            switch ( f )
                {
                case std::endl : my_ostream::endl( *this ) ;
                case std::ends : ; // etc
                }
            return *this ;
            }
    Ça ne compile pas et je n'ai encore compris pourquoi...
    Mais de toutes façons, je trouve ça assez moche.

    Quant à la solution de Jean-Marc Bourguet à base de streambuf, je ne la comprends pas...

Discussions similaires

  1. Comment créer son propre #quelquechose
    Par Joooooon dans le forum Visual Studio
    Réponses: 3
    Dernier message: 04/08/2010, 11h23
  2. Comment créer son propre Widget Gtkmm?
    Par Greensource dans le forum GTK+ avec C & C++
    Réponses: 2
    Dernier message: 08/04/2009, 11h41
  3. Comment créer son propre logo ?
    Par jojo_ol76 dans le forum Imagerie
    Réponses: 7
    Dernier message: 15/01/2008, 15h03
  4. Comment créer son propre iterator ?
    Par kidpaddle2 dans le forum C++
    Réponses: 9
    Dernier message: 02/04/2007, 22h02
  5. Comment créer son propre logiciel de gestion ?
    Par Sayanne dans le forum Autres Logiciels
    Réponses: 8
    Dernier message: 11/04/2006, 18h03

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