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 :

Problème de définition.


Sujet :

C++

  1. #1
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut Problème de définition.
    Bonjour à tous.

    J'ai un programme assez complexe, dans lequel j'ai une quinzaine d'occasions de vouloir utiliser exit() après avoir affiché un message.

    Voici le code de base pour ce genre de sorties
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (!condition) {
    	cerr << "erreur grave!" << endl;
    	exit(-4);
    }
    Plutôt que d'avoir quinze fois ce genre de choses, j'essaie d'obtenir: if (!condition) leave(-4) << "erreur grave!" << endl;Pour se faire, un peu naïvement, je raiie cerr en mettant l'appel à exit() dans le destructeur.
    Sauf que, ca ne compile pas avec g++ 4.4.5:
    Citation Envoyé par g++ -Wall -Wextra -Werror
    In function ‘int main()’:
    error: no match for ‘operator<<’ in ‘leaver(1) << "salut"’
    Voici mon programme de démonstration:
    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 <iostream>
    #include <cstdlib>
    class leaver {
    private:
    	int flag;
    public:
    	explicit leaver(int i) : flag(i) {}
    	~leaver() {::exit(flag);}
    };
     
    template <typename T>
    leaver& operator<<(leaver& leaver, T const& t) {
    	std::cerr << t;
    	return leaver;
    }
     
    int main() {
    	leaver(1) << "salut"<< std::endl;
    	return 0;
    }
    Quelqu'un a-t-il une suggestion?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    En fait, je suis juste bouché.
    Ca fait deux bonnes heures que j'essaie d'écrire ceci:
    Je m'explique:

    Puisque leaver est une classe, et leaver(int) son constructeur, leaver(1) crée une valeur de ce type.

    template <typename T> leaver& operator<<(leaver& leaver, T const& t); demande en argument une référence non constante.

    donc, avec leaver(1) << 1;, je tente de donner une valeur (temporaire, donc) à une référence non constante.

    gcc me dit qu'il ne connait pas de template valable, mais il aurai pu être plus gentil.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Moi je ne comprends pas parceque ce code marche chez moi (VS2012) https://github.com/artofsequence/uti...tilcpp/log.hpp

    Et qu'il est similaire.

    (meme si c'est pas une bonne idee et que je vais m'empresser de le remplacer par boost.log bientot)


    J'ai bien essaye ca sur gcc (http://coliru.stacked-crooked.com/):
    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
     
    #include <iostream>
    #include <cstdlib>
     
    class leaver {
    private:
        int flag;
    public:
    	explicit leaver(int i) : flag(i) {}
    	~leaver() {::exit(flag);}
     
    template <typename T>
    leaver& operator<<( const T& t) {
        std::cerr << t;
        return *this;
    }
     
     
    };
     
     
     
    int main() {
    	leaver(1) << "salut"<< std::endl;
    	return 0;
    }
    Mais j'obtiens plein d'erreurs, la premiere etant:
    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
     
    + g++-4.8 -std=c++11 -O2 -Wall -pedantic -pthread main.cpp
    main.cpp: In function 'int main()':
    main.cpp:23:22: error: no match for 'operator<<' (operand types are 'leaver' and '<unresolved overloaded function type>')
      leaver(1) << "salut"<< std::endl;
                          ^
    main.cpp:23:22: note: candidates are:
    main.cpp:12:9: note: template<class T> leaver& leaver::operator<<(const T&)
     leaver& operator<<( const T& t) {
             ^
    main.cpp:12:9: note:   template argument deduction/substitution failed:
    main.cpp:23:30: note:   couldn't deduce template parameter 'T'
      leaver(1) << "salut"<< std::endl;
                                  ^
    In file included from /usr/include/c++/4.8/iostream:39:0,

  4. #4
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Bonjour

    Tu essayes de modifier un temporaire.
    Soit tu instancies :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main()
    {
    	leaver l(1);
    	l << "salut\n";
    	return 0;
    }
    Soit tu passes ton leaver par référence sur membre constant (comme il n'est pas modifié) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <typename T>
    leaver const & operator<<(leaver const & leaver, T const & t)
    {
    	std::cerr << t;
    	return leaver;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main()
    {
    	leaver(1) << "salut\n";
    	return 0;
    }
    Pour endl, c'est une fonction qui prend un std::ostream donc je pense qu'il faut que ton leaver hérite d'un std::ostream.

  5. #5
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Ok donc c'est pour ca qu'en fait ma version marche mais pas avec std::endl.
    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
     
    #include <iostream>
    #include <cstdlib>
     
    class leaver {
    private:
        int flag;
    public:
    	explicit leaver(int i) : flag(i) {}
    	~leaver() {::exit(flag);}
     
    template <typename T>
    leaver& operator<<( const T& t) {
        std::cerr << t;
        return *this;
    }
     
     
    };
     
     
     
    int main() {
    	leaver(1) << "salut\n";
    	return 0;
    }
    Au passage, les temporaires ne sont pas const hein...

  6. #6
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Citation Envoyé par Klaim Voir le message
    Moi je ne comprends pas parceque ce code marche chez moi (VS2012) https://github.com/artofsequence/uti...tilcpp/log.hpp
    VS2012 peut appeler une fonction qui prend une référence alors qu'on lui donne un temporaire. C'est (à priori) pas standard.

  7. #7
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Citation Envoyé par Ehonn Voir le message
    VS2012 peut appeler une fonction qui prend une référence alors qu'on lui donne un temporaire. C'est (à priori) pas standard.
    GCC aussi comme je viens de le demontrer...

  8. #8
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Une version amelioree qui fait presque ce que tu veux...

    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
    #include <iostream>
    #include <cstdlib>
     
    class leaver {
    private:
        int flag;
    public:
    	explicit leaver(int i) : flag(i) {}
    	~leaver() 
        {
            std::cerr << std::endl;
            ::exit(flag);
        }
     
    template <typename T>
    leaver& operator<<( T&& t) {
        std::cerr << std::forward<T>(t);
        return *this;
    }
     
    };
     
     
     
    int main() {
    	leaver(1) << "salut";
    	return 0;
    }
    A priori std::endl etant une fonction il faudrait prendre carement un pointeur de fonction avec sa signature pour que passe.



    EDIT> A verifier dans le standard mais il me semble bien que les temporaires ne sont aps const, c'est les acces qu'on a aux temporaires qui ont besoin de l'etre. Voir http://stackoverflow.com/questions/6...does-this-work

  9. #9
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Lorsque je dis «modifier un temporaire» c'est modifier le temporaire lui même (pas une copie). Pour moi, c'est un peu comme si tu essayais de récupérer l'adresse d'un temporaire.

    Oui, mais tu as mis la déclaration dans la classe (les règles changent (?)).
    Si tu le sors et prend une référence sur un leaver; ça ne compile pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <typename T>
    leaver& operator<<(leaver & l, const T& t) {
        std::cerr << t;
        return l;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    main.cpp: In function ‘int main()’:
    main.cpp:22:12: erreur: no match foroperator<<’ (operand types are ‘leaver’ andconst char [7])
      leaver(1) << "salut\n";
                ^
    main.cpp:22:12: note: candidate is:
    main.cpp:16:9: note: template<class T> leaver& operator<<(leaver&, const T&)
     leaver& operator<<(leaver & l, const T& t) {
             ^
    main.cpp:16:9: note:   template argument deduction/substitution failed:
    main.cpp:22:15: note:   cannot convert ‘leaver(1)(type ‘leaver’) to type ‘leaver&’
      leaver(1) << "salut\n";
                   ^

  10. #10
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Citation Envoyé par Ehonn Voir le message
    Lorsque je dis «modifier un temporaire» c'est modifier le temporaire lui même (pas une copie). Pour moi, c'est un peu comme si tu essayais de récupérer l'adresse d'un temporaire.
    Dans toute la discussion il n'est pas question de copie du temporaire. Recuperer l'adresse d'un temporaire donne UB. Modifier la valeure d'un temporaire pendant qu'il est vivant n'est pas UB et est valide (voir le lien stackoverflow). En revanche, donner un nom a l'objet est invalide si on y accede pas en lecture seule (const ref ou via une copie).

    Oui, mais tu as mis la déclaration dans la classe (les règles changent (?)).
    Si tu le sors et prend une référence sur un leaver; ça ne compile pas :
    Si j'ai bien compris, dans le cas de la fonction externe, on donne un nom a l'objet, ce qui fait que dans ce cas precis le temporaire a un nom on dois y acceder en lecture seule (on peut forcer via un const cast mais alors UB).

    Du coup c'est logique: dans la fonction membre l'objet n'a pas de nom, tout ce qui se passe dans les membres ne peut se passer que le temps de vie de l'objet, donc c'est valide.

    J'ai utilise du code comme ca dans plein de projets sur plusieurs annees avec plusieurs compilo et OS differents (linux et windows) et ca a toujours marche. Pendant longtemps je pensais qu'un temporaire etait toujours const mais c'est pas exactement ca (et bien explique dans le lien stackoverflow).

  11. #11
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Merci pour ces explications

  12. #12
    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
    Un temporaire est un objet comme un autre, on peut en faire ce qu'on veut, la subtilité c'est qu'il va être détruit sous peu et qu'il faut donc prendre des précautions.

    Par exemple le code que tu donne plus haut pour operator<< Ehonn (le premier) est un gros risque d'UB. En effet je peux lui passer un temporaire, mais il va me retourner une référence invalide car le temporaire sera détruit à la sortie.

    On peut récupérer un temporaire via une const ref et le modifier en castant, le risque est que rien ne prévaut l'utilisateur de ne pas passer un objet qui est vraiment constant, ce qui donnerait un UB.

    De même on peut prendre adresse d'un temporaire, il n'y a aucun problème tant qu'on ne l'utilise que quand le temporaire est en vie.

    Ce qu'on ne peut pas faire c'est modifier un objet réellement constant et prendre l'adresse d'autre chose qu'une lvalue.

  13. #13
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Cela dit, en trichant un peu, on s'en sort aussi pour endl.
    il suffit de retourner cerr et non le leaver dans <<.

    Je m'en suis donc sorti avec ceci:
    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
    #include <iostream>
    #include <cstdlib>
    class leaver {
    private:
    	int flag;
    public:
    	explicit leaver(int i) : flag(i) {}
    	~leaver() {::exit(flag);}
     
    	template <typename T>
    	std::ostream& operator<<(T const& t) const {return std::cerr << t;}
    };
     
    int main() {
    	leaver(1) << "salut" << " a " << "tous" << std::endl;
    	return 0;
    }
    Ca remplit mon besoin, ca me suffira.

    Dans le cas où j'aurai voulu m'entêter à retourner le leaver, il aurait fallu une surcharge de operator<< pour prendre les fonctions en argument.

    Citation Envoyé par signature de endl
    template< class CharT, class Traits >
    std::basic_ostream<charT,traits>& endl( std::basic_ostream<CharT, Traits>& os);
    Merci pour le coup de main!
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  14. #14
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Note que si le premier argument est std::endl, ca compilera pas...

  15. #15
    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
    Sinon tu peux aussi écrire la surcharge pour prendre en compte les manipulateurs de flux.

    La signature a utilisé est celle qui correspond au charT et traits du flux que tu utilise (regarde dans la norme/doc la déclaration de cerr pour les avoirs). Et l'utilisation du manipulateur se fait juste en l'appelant sur ton flux.

    Si tu veux des exemples, en fouillant dans la norme/doc tu devrais voir comment les flux standard font.

    Cependant, si tu veux faire les choses proprement, tu définis un vrai flux en héritant du std::basic_ostream qui va bien, et tu te débrouilles pour l'attacher au buffer utilisé par std::cerr (en décrochant std::cerr ou non). Ainsi tu auras automatiquement tout ce qu'il faut.

  16. #16
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    C'est tout à fait vrai.

    C'est juste que je n'en ai pas besoin, dans mon cas.

    En fait, j'ai laissé le endl,mais j'aurai pu le placer silencieusement dans mon destructeur.

    C'est juste un critere d'esthétique.

    je pense plus cohérent pour le lecteur d'avoir le endl explicite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if(error) {
        leaver(-1) << "erreur: fichier invalide" << std::endl;
    }
    //me semble moins déroutant que ceci:
    if(error) {
        leaver(-1) << "erreur: fichier invalide";
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  17. #17
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Citation Envoyé par leternel Voir le message
    C'est tout à fait vrai.

    C'est juste que je n'en ai pas besoin, dans mon cas.

    En fait, j'ai laissé le endl,mais j'aurai pu le placer silencieusement dans mon destructeur.

    C'est juste un critere d'esthétique.

    je pense plus cohérent pour le lecteur d'avoir le endl explicite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if(error) {
        leaver(-1) << "erreur: fichier invalide" << std::endl;
    }
    //me semble moins déroutant que ceci:
    if(error) {
        leaver(-1) << "erreur: fichier invalide";
    }

    Perso je prefere avoir un flush explicite dans le destructeur de leaver et laisser l'utilisateur faire des sauts de ligne avec '\n' . Ca n'a rien de choquant je trouve.

  18. #18
    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
    Don tu trouves redondant de devoir écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    { std::cerr << "blabla" << std::endl; exit(x); }
    Mais dès que tu enlève un ";" et un"{}", tu trouves plus ça redondant ?

    Quitte à faire tu pourrais faire une fonction qui fait tout ca d'un coup, à l'appel tu pourrais avoir :
    C'est pas ce qui serait le moins redondant ?

  19. #19
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    En effet, une macro serait plus efficace pour pouvoir changer l'implementation dans le future si besoin.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define LOG_EXIT( error_code__ , expr__ ) leaver( error_code__ ) << expr
    Utilisation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LOG_EXIT( error_code, "Arg! Objet " << object.id() << " n'est pas valide!" );
    Si tu dois changer l'implementation, la macro restera valide.

  20. #20
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    La macro était possible, certes, mais je voulais pouvoir m'en sortir sans.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Système] Problème de définition des variables
    Par SLAM JACK dans le forum Langage
    Réponses: 6
    Dernier message: 29/03/2006, 19h53
  2. [Configuration] Problème sur définition de constante
    Par Yobs dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 4
    Dernier message: 24/03/2006, 11h40
  3. Réponses: 1
    Dernier message: 21/12/2005, 19h08
  4. Réponses: 2
    Dernier message: 17/08/2005, 11h20
  5. Réponses: 22
    Dernier message: 05/07/2005, 00h04

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