Frage

Das ist eigentlich keine Designfrage, auch wenn es so scheint.(Na gut, es ist eine Art Designfrage).Ich frage mich, warum das C++ std::fstream Der Unterricht dauert nicht std::string in ihrem Konstruktor oder ihren offenen Methoden.Jeder liebt Codebeispiele, also:

#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();
}

Das beschäftigt mich ständig, wenn ich mit Dateien arbeite.Sicherlich würde die C++-Bibliothek verwenden std::string woimmer möglich?

War es hilfreich?

Lösung

Durch die Verwendung eines C-Strings wird C++03 std::fstream Klasse reduzierte Abhängigkeit von der std::string Klasse.In C++11 jedoch std::fstream Klasse erlaubt das Bestehen von a std::string für seinen Konstruktorparameter.

Nun fragen Sie sich vielleicht, warum es keine transparente Konvertierung von a gibt std:string zu einem C-String, sodass eine Klasse, die einen C-String erwartet, immer noch a annehmen könnte std::string genau wie eine Klasse, die eine erwartet std::string kann einen C-String annehmen.

Der Grund dafür ist, dass dies zu einem Konvertierungszyklus führen würde, der wiederum zu Problemen führen kann.Nehmen wir zum Beispiel an std::string wäre in einen C-String konvertierbar, sodass Sie ihn verwenden könnten std::strings mit fstreamS.Nehmen wir auch an, dass C-Strings konvertierbar sind std::strings, wie es im aktuellen Standard der Fall ist.Bedenken Sie nun Folgendes:

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
}

Weil Sie in beide Richtungen zwischen a konvertieren können std::string und eine C-Zeichenfolge für den Aufruf f() könnte sich für eines der beiden entscheiden f() Alternativen und ist daher mehrdeutig.Die Lösung besteht darin, den Konvertierungszyklus zu unterbrechen, indem eine Konvertierungsrichtung explizit angegeben wird, wofür sich die STL entschieden hat c_str().

Andere Tipps

An mehreren Stellen hat das C++-Standardkomitee die Interaktion zwischen den Funktionen in der Standardbibliothek nicht wirklich optimiert.

std::string und seine Verwendung in der Bibliothek ist einer davon.

Ein weiteres Beispiel ist std::swap.Viele Container verfügen über eine Swap-Member-Funktion, es wird jedoch keine Überladung von std::swap bereitgestellt.Das gleiche gilt für std::sort.

Ich hoffe, dass all diese kleinen Dinge im kommenden Standard behoben werden.

Vielleicht ist es ein Trost:Alle Fstreams haben im Arbeitsentwurf des C++0x-Standards ein open(string const &, ...) neben open(char const *, ...) erhalten.(siehe z.B.27.8.1.6 für die basic_ifstream-Deklaration)

Wenn es also fertiggestellt und implementiert ist, wird es Sie nicht mehr erreichen :)

Die Stream-IO-Bibliothek wurde vor der STL zur Standard-C++-Bibliothek hinzugefügt.Um die Abwärtskompatibilität nicht zu beeinträchtigen, wurde beschlossen, beim Hinzufügen der STL keine Änderungen an der E/A-Bibliothek vorzunehmen, auch wenn dies zu Problemen wie dem von Ihnen angesprochenen führen würde.

@Bernard:
Monolithen "Ungestumpft". "Alles für einen und eines für alle" kann für Musketiere funktionieren, aber es funktioniert nicht annähernd so gut für Klassendesigner.Hier ist ein Beispiel, das nicht ganz vorbildlich ist und zeigt, wie viel man falsch machen kann, wenn Design zu Überdesign wird.Das Beispiel stammt leider aus einer Standardbibliothek in Ihrer Nähe ...~ http://www.gotw.ca/gotw/084.htm

Es ist belanglos, das stimmt.Was meinst du damit, dass die Schnittstelle von std::string groß ist?Was bedeutet groß in diesem Zusammenhang – viele Methodenaufrufe?Ich bin nicht scherzhaft, ich bin tatsächlich interessiert.

Sie verfügt über mehr Methoden, als sie wirklich benötigt, und ihr Verhalten, integrale Offsets anstelle von Iteratoren zu verwenden, ist etwas fragwürdig (da es im Gegensatz zur Funktionsweise des Rests der Bibliothek steht).

Das eigentliche Problem besteht meiner Meinung nach darin, dass die C++-Bibliothek aus drei Teilen besteht;Es hat die alte C-Bibliothek, es hat die STL und es hat Strings-and-Iostreams.Obwohl einige Anstrengungen unternommen wurden, um die verschiedenen Teile zu überbrücken (z. B.das Hinzufügen von Überladungen zur C-Bibliothek, da C++ Überladungen unterstützt;das Hinzufügen von Iteratoren zu basic_string;Durch die Hinzufügung der iostream-Iterator-Adapter gibt es viele Inkonsistenzen, wenn man sich die Details ansieht.

Beispielsweise enthält „basic_string“ Methoden, die unnötige Duplikate von Standardalgorithmen sind.Die verschiedenen Suchmethoden könnten wahrscheinlich sicher entfernt werden.Ein anderes Beispiel:Gebietsschemas verwenden Rohzeiger anstelle von Iteratoren.

C++ ist auf kleineren Maschinen entstanden als die Monster, für die wir heute Code schreiben.Als iostream neu war, legten viele Entwickler großen Wert auf die Codegröße (sie mussten ihr gesamtes Programm und ihre Daten in mehrere hundert KB unterbringen).Daher wollten viele nicht auf die „große“ C++-String-Bibliothek zurückgreifen.Viele nutzten die iostream-Bibliothek aus den gleichen Gründen, nämlich der Codegröße, nicht einmal.

Wir hatten nicht wie heute Tausende von Megabyte RAM, die wir herumwerfen konnten.Normalerweise verfügten wir nicht über eine Verknüpfung auf Funktionsebene, sodass wir dem Entwickler der Bibliothek ausgeliefert waren, viele separate Objektdateien zu verwenden oder Unmengen an nicht aufgerufenem Code einzubinden.All diese FUDs führten dazu, dass Entwickler von std::string abrücken.

Damals habe ich auch std::string gemieden.„Zu aufgebläht“, „zu oft Malloc genannt“ usw.Es ist törichterweise, stapelbasierte Puffer für Zeichenfolgen zu verwenden und dann alle Arten von mühsamem Code hinzuzufügen, um sicherzustellen, dass es nicht zu einem Überlauf kommt.

Gibt es eine Klasse in STL, die einen String akzeptiert ...Ich glaube nicht (konnte in meiner Schnellsuche keine finden).Es ist also wahrscheinlich eine Entwurfsentscheidung, dass keine Klasse in STL von einer anderen STL-Klasse abhängig sein sollte (die für die Funktionalität nicht direkt benötigt wird).

Ich glaube, dass darüber nachgedacht und getan wurde, um die Abhängigkeit zu vermeiden;d.h.#include <fstream> sollte nicht dazu zwingen, #include <string> zu verwenden.

Um ehrlich zu sein, scheint dies ein ziemlich belangloses Problem zu sein.Eine bessere Frage wäre: Warum ist die Schnittstelle von std::string so groß?

Heutzutage können Sie dieses Problem ganz einfach lösen:hinzufügen -std=c++11 zu deinem CFLAGS.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top