Question

Ce n'est pas une question de conception, vraiment, même si il peut sembler comme il.(Bon, d'accord, c'est un peu une question de conception).Ce que je me pose, c'est pourquoi le C++ std::fstream les classes ne prenez pas un std::string dans leur constructeur ou des méthodes ouvertes.Tout le monde aime les exemples de code ainsi:

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::string filename = "testfile";      
    std::ifstream fin;

    fin.open(filename.c_str()); // Works just fine.
    fin.close();

    //fin.open(filename); // Error: no such method.
    //fin.close();
}

Cela me fait tout le temps lorsque vous travaillez avec des fichiers.Sûrement la bibliothèque C++ serait d'utiliser std::string dans la mesure du possible?

Était-ce utile?

La solution

En prenant une chaîne C, le C++03 std::fstream classe de réduire la dépendance sur le std::string classe.En C++11, cependant, l' std::fstream la classe ne permettent le passage d'un std::string pour sa paramètre du constructeur.

Maintenant, vous demandez peut-être pourquoi il n'existe pas de conversion transparentes à partir d'un std:string pour une chaîne C, donc une classe qui s'attend à une chaîne C pourrait encore prendre un std::string tout comme une classe qui attend un std::string pouvez prendre une chaîne C.

La raison en est que ce serait la cause d'un cycle de conversion, qui à son tour peut conduire à des problèmes.Par exemple, supposons que std::string serait convertible pour une chaîne C de sorte que vous pouvez utiliser std::strings avec fstreams.Supposons aussi que C de la chaîne sont convertibles à std::strings est l'état dans la norme actuelle.Maintenant, considérez les points suivants:

void f(std::string str1, std::string str2);
void f(char* cstr1, char* cstr2);

void g()
{
    char* cstr = "abc";
    std::string str = "def";
    f(cstr, str);  // ERROR:  ambiguous
}

Parce que vous pouvez convertir entre une std::string et une chaîne C de l'appel à f() pourraient résoudre à l'une des deux f() des solutions de rechange, et est donc ambigu.La solution est de briser le cycle de conversion en faisant un sens de conversion explicite, qui est ce que la STL a choisi de le faire avec c_str().

Autres conseils

Il y a plusieurs endroits où la norme C++ comité n'a pas réellement d'optimiser l'interaction entre les installations de la bibliothèque standard.

std::string et son utilisation dans la bibliothèque est l'un de ces.

Un autre exemple est std::swap.De nombreux conteneurs ont un swap fonction de membre, mais pas de surcharge de std::swap est fourni.Il en va de même pour std::sort.

J'espère que toutes ces petites choses seront fixées dans la norme à venir.

C'est peut-être une consolation:tous les fstream ont obtenu un open(string const &, ...) à côté de l'open(const char *, ...) dans le projet de C++0x standard.(voir par ex.27.8.1.6 pour la basic_ifstream déclaration)

Alors quand il fait finalisé et mis en œuvre, il ne sera pas vous plus :)

Le flux IO bibliothèque a été ajouté à la bibliothèque C++ standard devant le TSL.Afin de ne pas casser la compatibilité ascendante, il a été décidé d'éviter la modification de l'OI de la bibliothèque lors de la TSL a été ajouté, même si cela signifiait que certaines questions comme celle que vous soulevez.

@ Bernard:
Les Monolithes "Pendeloques." "Tous pour un et un pour tous" peut travailler pour les Mousquetaires, mais il ne fonctionne pas aussi bien pour les concepteurs de classe.Voici un exemple qui n'est pas du tout exemplaire, et il montre à quel point vous pouvez aller mal quand le design se transforme en overdesign.L'exemple est, malheureusement, prises à partir d'un standard de la bibliothèque près de chez vous...~ http://www.gotw.ca/gotw/084.htm

Il est sans importance, ce qui est vrai.Qu'entendez-vous par std::string s de l'interface d'être grand?Ce n'grand signifie, dans ce contexte, beaucoup d'appels de méthode?Je ne suis pas en train facétieux, je suis réellement intéressé.

Il a plus de méthodes qu'il a vraiment besoin, et de son comportement à l'aide de l'intégrale des décalages plutôt que de les itérateurs est un peu douteux (comme c'est contraire à la façon dont le reste de la bibliothèque d'œuvres).

Le vrai problème est, je pense que le C++ de la bibliothèque est constitué de trois parties;c'est l'ancien de la bibliothèque C, il a la STL, et il a des cordes-et-iostreams.Même si certains efforts ont été faits pour combler les différentes parties (par ex.l'ajout de surcharges de la bibliothèque C, parce que le C++ prend en charge la surcharge;l'ajout d'itérateurs pour basic_string;l'ajout de la iostream itérateur adaptateurs), il y a beaucoup d'incohérences quand vous regardez dans le détail.

Par exemple, basic_string inclut des méthodes qui sont inutiles, les doublons des algorithmes standard;les différentes méthodes de recherche, pourrait probablement être retiré en toute sécurité.Un autre exemple:paramètres régionaux d'utiliser des pointeurs au lieu de les itérateurs.

C++ a grandi sur les machines plus petites que les monstres nous écrire du code pour aujourd'hui.En arrière quand iostream a nouveau, de nombreux développeurs se souciait vraiment de la taille du code (ils avaient pour s'adapter à l'ensemble de leur programme et de données de plusieurs centaines de KO).Par conséquent, beaucoup n'ont pas envie de tirer dans le "grand" C++ de la bibliothèque string.Beaucoup n'ont même pas utiliser la bibliothèque iostream pour les mêmes raisons, la taille du code.

Nous n'avons pas eu des milliers de méga-octets de RAM pour jeter autour comme nous le faisons aujourd'hui.Nous avons l'habitude de ne pas avoir de niveau de la fonction de liaison de sorte que nous étions à la merci de la part du développeur de la bibliothèque à utiliser beaucoup d'objet distinct des fichiers ou encore pull dans les tons souscrit non appelé de code.Tout cela FUD fait les développeurs à se détourner de la std::string.

De retour alors j'ai évité std::string trop."Trop lourd", "appelé malloc trop souvent", etc.Bêtement à l'aide de pile, tampons pour les cordes, puis en y ajoutant toutes sortes de codes pour s'assurer qu'il n'a pas de dépassement.

Est-il toutes les classes de la STL qui prend une chaîne de caractères...Je ne pense pas (ne pourrais pas trouver dans mes recherche rapide).Donc c'est probablement une décision de conception, qu'aucune classe dans la STL doit être dépend d'aucun autre STL classe (qui n'est pas directement nécessaire pour la fonctionnalité).

Je crois que cela a été pensé, et a été fait pour éviter la dépendance;c'est à dire#include <fstream> ne devrait pas forcer l'un d' #include <string>.

Pour être honnête, cela semble être tout à fait un sans conséquence problème de.Une meilleure question serait, pourquoi est std::string s de l'interface si grand?

Aujourd'hui, vous pouvez résoudre ce problème très facilement:ajouter -std=c++11 pour votre CFLAGS.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top