c++ - write - stringstream




Warum nehmen die std:: fstream-Klassen keine std:: string? (7)

Es ist belanglos, das ist wahr. Was meinst du damit, dass die Schnittstelle von std :: string groß ist? Was bedeutet groß in diesem Zusammenhang - viele Methodenaufrufe? Ich bin nicht witzig, ich bin wirklich interessiert.

Es hat mehr Methoden, als es wirklich benötigt, und sein Verhalten bei der Verwendung von Integral-Offsets anstelle von Iteratoren ist ein bisschen zweifelhaft (wie es im Gegensatz zu dem Rest der Bibliothek steht).

Das wirkliche Problem, das ich denke, ist, dass die C ++ Bibliothek drei Teile hat; Es hat die alte C-Bibliothek, es hat die STL, und es hat Strings-und-Iostreams. Obwohl einige Anstrengungen unternommen wurden, um die verschiedenen Teile zu überbrücken (z. B. das Hinzufügen von Überladungen zur C-Bibliothek, weil C ++ das Überladen unterstützt; das Hinzufügen von Iteratoren zu basic_string; das Hinzufügen der Iostream-Iteratoradapter), gibt es viele Inkonsistenzen bei Ihnen schau dir das Detail an.

Zum Beispiel enthält basic_string Methoden, die unnötige Duplikate von Standardalgorithmen sind; Die verschiedenen Suchmethoden könnten wahrscheinlich sicher entfernt werden. Ein anderes Beispiel: Locales verwenden rohe Zeiger anstelle von Iteratoren.

Dies ist keine Designfrage, wirklich, obwohl es so aussieht. (Nun, okay, es ist eine Designfrage). Was ich frage mich ist, warum die C ++ std::fstream Klassen nicht eine std::string in ihrem Konstruktor oder offenen Methoden nehmen. Jeder liebt Codebeispiele so:

#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 bringt mir die ganze Zeit beim Arbeiten mit Dateien. Sicher würde die C ++ Bibliothek wo immer möglich std::string ?


@ Bernard:
Monolithen "Ungespannt" "Alle für einen, und einer für alle" mag für Musketiere funktionieren, aber es funktioniert nicht annähernd so gut für Klassenkünstler. Hier ist ein Beispiel, das nicht ganz beispielhaft ist, und es zeigt, wie sehr man schief gehen kann, wenn Design zu Überdesign wird. Das Beispiel stammt leider aus einer Standardbibliothek in Ihrer Nähe ... ~ http://www.gotw.ca/gotw/084.htm


Die Stream-E / A-Bibliothek wurde der Standard-C ++ - Bibliothek vor der STL hinzugefügt. Um die Abwärtskompatibilität nicht zu unterbrechen, wurde entschieden, die IO-Bibliothek beim Hinzufügen der AWL nicht zu verändern, selbst wenn das einige Probleme wie die von Ihnen angesprochene hatte.


Durch die Verwendung einer C-Zeichenfolge reduzierte die Klasse C ++ 03 std::fstream die Abhängigkeit von der Klasse std::string . In C ++ 11 jedoch std::fstream Klasse std::fstream die Übergabe einer std::string für ihren Konstruktorparameter.

Nun können Sie sich wundern, warum es keine transparente Umwandlung von einer std:string in eine C string gibt, so dass eine Klasse, die eine C-Zeichenfolge erwartet, immer noch eine std::string wie eine Klasse, die eine std::string erwartet kann eine C-Zeichenfolge nehmen.

Der Grund ist, dass dies einen Umwandlungszyklus verursachen würde, was wiederum zu Problemen führen könnte. Angenommen, std::string wäre in eine C-Zeichenfolge konvertierbar, sodass Sie std::string s mit fstream s verwenden fstream . Angenommen, die C-Zeichenfolge ist in std::string s konvertierbar, ebenso wie der Status im aktuellen Standard. Betrachten 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
}

Da Sie beide Wege zwischen einer std::string und einer C string konvertieren können, könnte der Aufruf von f() in eine der beiden f() Alternativen aufgelöst werden und ist daher nicht eindeutig. Die Lösung besteht darin, den Konvertierungszyklus zu c_str() indem eine Konvertierungsrichtung explizit gemacht wird, was die STL mit c_str() .


Gibt es irgendeine Klasse in STL, die eine Zeichenkette nimmt ... Ich glaube nicht (konnte in meiner schnellen Suche keine finden). Daher ist es wahrscheinlich eine Designentscheidung, dass keine Klasse in STL von irgendeiner anderen STL-Klasse abhängig sein sollte (die nicht direkt für die Funktionalität benötigt wird).


Heutzutage können Sie dieses Problem sehr leicht lösen: fügen Sie -std=c++11 zu Ihren CFLAGS .


Vielleicht ist es ein Trost: Alle Stream's haben eine offene (String const &, ...) neben dem offenen (char const *, ...) im Arbeitsentwurf des C ++ 0x-Standards bekommen. (siehe zB 27.8.1.6 für die basic_ifstream-Deklaration)

Wenn es fertiggestellt und implementiert wird, wird es dich nicht mehr bringen :)





stdstring