• [^] # Re: Une si bonne API

    Posté par . En réponse à la dépêche Sortie de Qt 4.6. Évalué à 2.

    > Ce qui me laisse plus dubitatif au niveau simplicité, c’est l’implémentation de tee_device.
    Voici comment faire sans bibliothèque extérieure.

    #include
    #include
    #include

    class TeeBuf: public std::streambuf
    {
    public:
    TeeBuf(std::streambuf * buf1, std::streambuf * buf2): buf1(buf1), buf2(buf2) {}
    private:
    int overflow(int c)
    {
    if (c == EOF) {
    return !EOF;
    } else {
    return (EOF == buf1->sputc(c)) || (EOF == buf2->sputc(c)) ? EOF : c;
    }
    }
    int sync()
    {
    return (0 == buf1->pubsync()) && (0 == buf2->pubsync()) ? 0 : -1;
    }
    private:
    std::streambuf * buf1;
    std::streambuf * buf2;
    };

    class TeeStream : public std::ostream
    {
    public:
    TeeStream(std::ostream &o1, std::ostream &o2) : std::ostream(&buf), buf(o1.rdbuf(), o2.rdbuf()) {}
    private:
    TeeBuf buf;
    };

    int main()
    {
    using std::cout;
    std::ofstream ofs("mon_fichier.txt");
    /* avec TeeBuf */
    std::streambuf *sortieLog = ofs.rdbuf();
    std::streambuf *sortieStandard = cout.rdbuf();
    TeeBuf *teeBuf = new TeeBuf(sortieStandard, sortieLog);
    std::streambuf *oldBuf = cout.rdbuf(teeBuf);
    cout<<"hello ";
    cout.rdbuf(oldBuf);
    /* avec TeeStream c'est un poil plus agréable */
    TeeStream tee(cout, ofs);
    tee<<"world!"<<std::endl;

    ofs.close();
    return 0;
    }


    > Et comme dit également plus haut, ce sont les méthodes standard de la librairie standard qui nous intéressent. Si la librairie standard n’est même pas fichue de faire des IO adaptables simplement, autant ne pas s’embêter à en fournir une.

    Tu soulèves un dilemme qui touche tout les concepteurs de langages de programmation, quel doit être le contenu de la bibliothèque standard ?
    C++ a fait le choix de fournir un système d'entrée/sortie souple et puissant (pas super compliqué) mais très rugueux, c'est un choix parmi d'autre.

    > Je ne suis pas un développeur C++, juste un curieux, curieux de comprendre comment on peut appeler « supérieur » un système d’IO qui nécessite de connaître en profondeur les subtilités d’un langage réputé très complexe

    Il est pas si complexe que ça, les IO Java sont bien plus tordues que ça à mon avis.
    Si tu te limites à de l'affichage console, l'écriture dans des fichiers, c'est pas plus compliqué qu'avec les entrées/sorties C. Là, on s'attaque à un problème bien spécifique: i18n.
    On peut s'attaquer aux entrées/sorties sans forcément devoir s'occuper des détails, std::string est également une spécialisation d'une classe templaté et ça ne pose pas de problèmes.

    Enfin, si c'est pour faire du C en C++ sans utiliser les fonctionnalités avancés (stdio, pas de RAII, pas d'exception, pas de templates etc ..), autant faire du C.

    > Est-ce la faute du langage ou du développeur si la base (les IO) de la base (la librairie standard) n’est pas simplement assimilable ?

    Je dirais les deux, d'une part, C++ est un langage assez rugueux, de l'autre, C++ est très mal enseigné ce qui n'aide pas. Les concepteurs du langage en sont conscients (C++0x va dans ce sens) et cherchent à simplifier le langage.
    C++ n'est clairement pas un langage adapté à des débutants en programmation, même si le dernier bouquin de Stroustrup (adaptation de son cours à des 1ères années de fac) démontre que c'est possible (une traduction est en cours aux éditions Pearson fr).
    Dans le bouquin, il enseigne un style de programmation C++ moderne et n'aborde le sous-ensemble C du C++ que dans le dernier chapitre tout en restant accessible à tous.

    Que ce soit en C ou en C++, si tu te limites à la bibliothèque standard, tu risques pas d'aller bien loin. Boost est aussi essentiel à un développeur C++, que Posix l'est à un développeur C.