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 :

‘std::ofstream’ has no member named ‘swap’ en C++11 ?


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Points : 109
    Points
    109
    Par défaut ‘std::ofstream’ has no member named ‘swap’ en C++11 ?
    Bonjour, j'ai un probleme de manipulation de stream.
    Voilà une partie du code :

    Pour le header (Driver.hh) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    class Driver{
    //Plein de trucs....
    // dont 
    void setFileIn(const std::string& filein); // Fait ce qu'elle doit faire pour le fichier de données.
    //.....
    public :
     
    std::string fileoutname;
    std::ostream& outstream = std::cout;
     
    Driver(const std::string& filein="",const std::string& fileout="");
     
    };
    Pour l'implementation (Driver.cc)
    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
     
    #include"Driver.hh"
    //plein de trucs...
    //......
     
    Driver::Driver(const std::string& filein/*=""*/, const std::string& fileout/*=""*/)
    {
      if(!filein.empty())
        {setFileIn(filein);}
      if(!fileout.empty())
        {
          std::ofstream tmp (fileout.c_str());
          tmp.swap(outstream);
        }
    }
    Je compile bien avec le standard C++11 justement pour swap :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    g++ -c -std=c++11 Driver.cc
    Et la première (mais pas la dernière !!) erreur du compilateur me dit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    In constructor ‘Driver::Driver(const string&, const string&)’:
    Driver.cc:64:11: error: ‘std::ofstream’ has no member named ‘swap’
           tmp.swap(outstream);
               ^
    Pourtant ici on me dit le contraire...

    Une idée ? (sur ce problème... ou sur une autre facon de faire, je suis preneur !)

  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
    Bonjour,

    Quel version de GCC ? Il est probable que cette fonctionnalité n'ai pas été implémentée dans ta version, je ne sais plus où en est gcc, mais je crois que si niveau langage il est presque à 100% du C++11, niveau bibliothèque ce n'est pas le cas.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Points : 109
    Points
    109
    Par défaut
    j ai la 4.8.1...
    bon, j vais me reposer et j réfléchirai a ça plus tard.
    Merci en tout cas, je pensais que les compilateurs étaient prêts dès la 'sortie' des standards...
    Apparemment je n'ai pas bien compris comment les choses évoluent

  4. #4
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Qu'à partir de gcc-5.0.

    2 remarques:
    - fstream peut prendre un std::string, plus besoin de c_str().
    - swap s'applique sur un type équivalent. Ton code ne compilera pas car outstream est un ostream et tmp un ofstream.

    Tu peux regarder vers std::ostream::rdbuf, cela suffit peut-être ?

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Points : 109
    Points
    109
    Par défaut
    En fait j imagine que vous comprenez que je veux que la sortie soit au choix la sortie standard ou un fichier sans pour autant changer la variable qui represente cette sortie.
    J ai lu au sujet de rdbuf et ca a l air de pouvoir faire l affaire.
    si vous voyez un autre moyen de le faire ou si vous trouvez ma maniere de faire ridicule dites le moi svp.

  6. #6
    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
    Changer le buffer peut se faire.
    Il y a une autre possibilité, c'est d'utiliser un stream autre (genre BaygonV::out), que tu déclares comme tu en as besoin.

    Dernière possibilité, faire une redirection du flux de sortie standard (vers le fichier) non pas dans le programme mais à l'appel.
    ./programme >fichier
    Ainsi, le programme ne se pose pas la question, et si l'utilisateur veut intercaler un grep, un tee ou que sais-je encore, il peut le faire.
    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

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Points : 109
    Points
    109
    Par défaut
    Merci pour vos réponses et je suis intéressé (depuis bien avant l'apparition de ce fil ici) par avoir mon propre stream à la manière (si j'ai bien compris) de ce que propose leternel ici :
    Il y a une autre possibilité, c'est d'utiliser un stream autre (genre BaygonV::out), que tu déclares comme tu en as besoin.
    Et en effet j'ai essayé ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Driver::Driver(const std::string& filein/*=""*/, const std::string& fileout/*=""*/)
    {
      if(!filein.empty())
        {setFileIn(filein);}
      if(!fileout.empty())
        {
          outstream = *(new std::ofstream(fileout.c_str()));
     
        }
      else{outstream = std::cout; }
    }
    mais dans ce cas j'ai droit à un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    error: use of deleted function ‘std::basic_ostream<char>& std::basic_ostream<char>::operator=(const std::basic_ostream<char>&)’
           outstream = *(new std::ofstream(fileout.c_str()));
    C'est l'impossibilité d'utiliser cet opérateur = pour affecter mon ostream qui m'a fait chercher un moyen de contournement...
    J'ai pas du comprendre un (plusieurs ?) truc(s ?).

    EDIT : Je pense me rendre compte que j'ai effectivement oublié comment fonctionnent les flux... je vais donc me faire des petits exemples. Cependant je suis preneur de toute remarque (pas trop méchante ).

  8. #8
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    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.

  9. #9
    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
    Ou l'autre exemple, qu'on trouve sur cppreference: basic_ios::rdbuf
    Il est un peu plus C++11-esque. (et je préfère le style de la description de fonction, mais c'est mon goût)
    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

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Points : 109
    Points
    109
    Par défaut
    Merci j ai lu ces deux exemples déjà mais j aime moyen le fait que toute information envoyee sur cout finisse dans un fichier par inadvertance(meme si c est l inadvertance qu il faudrait chasser). Bref j ai fait autre chose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    class Driver {
     std::ostream* poutstream;
     bool ostreamdelete;
    Driver(const std::string& i="", const std::string& o="");
    virtual~Driver(){
    if(ostreamdelete) delete poutstream;}
    };
     
    Driver::Driver(const std::string& i/*=""*/, const std::string& o/*=""*/){
    if(!i.empty()){yyin=setInFile(i);} //setInFile s arrange avec l existance de i.
    if(o.empty()){poutstream=&cout; ostreamdelete=false;}
    else{poutstream=new std::ofstream(o);ostreamdelete=true;}
    }
    J en suis pas tres fier mais je l ai fait.

  11. #11
    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
    au moins, code le bien.
    Je n'arrive même pas à lire ton code.

    La même chose mieux présentée

    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
    class Driver {
    private:
        std::ostream* out;
        bool out_needs_delete;
    public:
        Driver(const std::string& i="", const std::string& o="");
        virtual ~Driver(){
            if (out_needs_delete) delete out;
        }
    };
     
    //la création, c'est délicat, il faut le faire dans la création
    Driver::Driver(const std::string& i, const std::string& o) :
        yyin ( (!i.empty())? setInFile(i) : 0),
        out(o.empty() ? &cout : new std::ofstream(o)),//je me permets un new ici, car c'est le seul.
        out_needs_delete(!o.empty())
    {}
    Et c'est quand même maladroit.
    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

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Points : 109
    Points
    109
    Par défaut
    Désolé pour la présentation, j aurais du patienter et ne pas écrire le code sur mon téléphone...

    Peux tu me dire en quoi c est maladroit ?
    Je n'ai pour ma part que l'impression de maladresse sans arriver a me donner des arguments...

    Tu ne pouvais pas savoir (et j'aurais mieux fait de ne pas le mettre...) mais le yyin n'est pas un membre de la classe Driver, c'est une variable globale qui est définie par un scanner généré par flex.

  13. #13
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par BaygonV Voir le message
    Merci j ai lu ces deux exemples déjà mais j aime moyen le fait que toute information envoyee sur cout finisse dans un fichier par inadvertance(meme si c est l inadvertance qu il faudrait chasser)
    Faut savoir : tu veux rediriger un flux ou non ?
    Si tu veux rediriger un flux, tu le rediriges entièrement. Je vois pas où est l'inadvertance là-dedans ?
    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.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Points : 109
    Points
    109
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Faut savoir : tu veux rediriger un flux ou non ?
    Alors alors.... la réponse à cette question est en fait : j'en sais rien car je me suis construit une définition de flux qui n'est peut-être pas la bonne...

    Pour moi un flux c'est un moyen d'écrire ou lire des informations quelque part sans avoir à "mettre les mains dans le cambouis" et laisser la responsabilité de la gestion de la lecture/écriture et autres buffers à des gens plus doués que moi.
    Si cette définition n'est pas trop loin de la réalité alors oui je veux rediriger un flux.

    Sinon, je rentre un peu plus dans les détails de ce qui m'a amené à vouloir faire ça :

    Je veux écrire un scanner (généré par flex) qui doit envoyer des informations vers divers endroits (fichiers ou autres processus).
    Les divers destinataires sont liés a des paramètres qui lui sont parfois inconnus et qui sont maitrisés par ma classe Driver.
    De plus, lorsqu'il s'agit d'informations à distribuer dans des fichiers, il s'agit ni plus ni moins que de recopier le caractère lu par le scanner.

    Pour arriver à faire ça, j'ai donc :

    L'important pour moi est que le scanner n'ait pas à ce soucier réellement de l'endroit où il doit faire ses ECHO.
    Ce sont donc les informations recueillies par ce flux pointé par driver.poutstream que je dois rediriger ensuite, selon le contexte, dans (un, plusieurs ou aucun) fichier(s) ou sur la sortie standard.

    Citation Envoyé par Bousk Voir le message
    Si tu veux rediriger un flux, tu le rediriges entièrement. Je vois pas où est l'inadvertance là-dedans ?
    Si j'utilise des rdbuf et que je crois écrire à droite alors que j'écris effectivement à gauche, ça me pose problème...
    mais encore une fois c'est peut être parce que je n'ai pas correctement compris ce qu'est un flux.

  15. #15
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par BaygonV Voir le message
    Ce sont donc les informations recueillies par ce flux pointé par driver.poutstream que je dois rediriger ensuite, selon le contexte, dans (un, plusieurs ou aucun) fichier(s) ou sur la sortie standard.
    Dans ce cas c'est pas du tout de la redirection, c'est un simple dispatch.
    Tu crées une classe qui gère les différentes sorties et fait elle-même le dispatch dans l'une ou l'autre.
    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.

  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
    Ca ressemble à du log, et tu peux peut-être t'inspirer de la structure de bibliothèque comme log4cpp.
    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 régulier
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 142
    Points : 109
    Points
    109
    Par défaut
    Ok je vais voir ça mais du coup.... bon je vais surement poser une question bête dans un nouveau fil après m'être renseigné un peu.
    Par contre ci vous pouviez me dire en quoi le dernier code que j'ai proposé est maladroit je pense que ca me ferait pas mal progresser.
    Personnellement dans ce code, je n aime pas du tout l'idée que je ne sache pas a coup sur si mon poustream est un truc à détruire ou pas et la présence du bool a tester pour le savoir me semble être la preuve de la maladresse. Y a t il un moyen de l’éviter ? Ou est ce que "c'est la vie" finalement ?

Discussions similaires

  1. Réponses: 2
    Dernier message: 09/12/2011, 08h03
  2. [Compilation] Erreur : "has no member named"
    Par Trademark dans le forum Débuter
    Réponses: 8
    Dernier message: 03/05/2010, 22h11
  3. plantage std::ofstream impossible à récupérer ?
    Par Captain_JS dans le forum C++
    Réponses: 1
    Dernier message: 24/08/2007, 15h40
  4. structure has no mumber named 'annee'.
    Par moon93 dans le forum C
    Réponses: 30
    Dernier message: 02/08/2006, 17h11

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