Domanda

Questa non è una questione di design, davvero, anche se può sembrare.(Beh, ok, è un po ' una questione di design).Quello che mi chiedo è perché il C++ std::fstream classi di non prendere una std::string nella loro funzione di costruzione o di metodi aperti.Tutti amano esempi di codice così:

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

Questo mi prende tutto il tempo quando si lavora con i file.Sicuramente la libreria C++ vorresti utilizzare std::string laddove possibile?

È stato utile?

Soluzione

Prendendo un C string del C++03 std::fstream classe ridotta dipendenza std::string classe.In C++11, tuttavia, il std::fstream classe non consentire il passaggio di un std::string per il suo parametro del costruttore.

Ora, ci si potrebbe chiedere perché non c'è un trasparente processo di conversione da una std:string per un C string, quindi una classe che si aspetta una stringa C potrebbe ancora prendere un std::string proprio come una classe che prevede un std::string può prendere un C string.

La ragione è che questo causerebbe un ciclo di conversione, che a sua volta può portare a problemi.Per esempio, supponiamo che std::string sarebbe convertibile per un C string in modo che si potrebbe utilizzare std::strings con fstreams.Supponiamo anche che il C string sono convertibili in std::strings come è stato nella norma vigente.Ora, consideriamo il seguente:

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
}

Perché è possibile convertire tra un std::string e un C string chiamata a f() è in grado di risolvere uno dei due f() alternative, ed è così ambiguo.La soluzione è quello di rompere il ciclo di conversione facendo una direzione di conversione esplicita, che è ciò che il STL ha scelto di fare con c_str().

Altri suggerimenti

Ci sono diversi luoghi in cui il C++ standard comitato non si è davvero per ottimizzare l'interazione tra strutture nella libreria standard.

std::string e il suo uso in biblioteca è uno di questi.

Un altro esempio è std::swap.Molti contenitori hanno una funzione membro di scambio, ma non sovraccarico di std::swap è fornito.Lo stesso vale per std::sort.

Spero che tutte queste piccole cose sarà fissato nei prossimi standard.

Forse è una consolazione:tutti del fstream hanno ottenuto un open(string const &, ...) accanto alla open(const char *, ...) nella bozza del C++0x standard.(vedi ad es.27.8.1.6 per il basic_ifstream dichiarazione)

Così, quando si ottiene finalizzati e implementato, non è più :)

Stream IO library è stato aggiunto alla libreria standard di C++ prima di STL.Per non rompere la compatibilità, è stato deciso per evitare di modificare l'IO library quando il STL è stato aggiunto, anche se questo significava alcuni problemi come quello che si alza.

@ Bernardo:
Monoliti Di "Unstrung." "Tutti per uno e uno per tutti" possono lavorare per i Moschettieri, ma non funziona altrettanto bene per classe di progettisti.Ecco un esempio che non è del tutto esemplare, e dimostra quanto male si può andare male quando il design si trasforma in overdesign.L'esempio è, purtroppo, preso da una libreria standard vicino a te...~ http://www.gotw.ca/gotw/084.htm

È irrilevante, ciò che è vero.Che cosa si intende per std::string interfaccia di essere grande?Ciò che fa grande significa, in questo contesto, un sacco di chiamate di metodo?Io non sono di essere spiritoso, io sono effettivamente interessati.

Ha più metodi che ne ha realmente bisogno, e il suo comportamento di utilizzo integrale offset piuttosto che iteratori è un po ' incerto (come è contrario al modo in cui il resto della biblioteca funziona).

Il vero problema credo è che il C++ library ha tre parti;è la vecchia libreria C, ha la STL, e ha corde-e-iostreams.Anche se alcuni sono stati fatti sforzi per colmare le diverse parti (ad es.l'aggiunta di sovraccarichi, per la libreria C che il C++ supporta sovraccarico;l'aggiunta di iteratori per basic_string;l'aggiunta di iostream iteratore adattatori), ci sono un sacco di incongruenze quando si guarda il dettaglio.

Per esempio, basic_string include metodi che sono inutili duplicati di algoritmi standard;i vari metodi di ricerca, probabilmente potrebbe essere rimosso in modo sicuro.Un altro esempio:locali uso a crudo puntatori invece di iteratori.

C++ è cresciuto su macchine più piccole rispetto ai mostri scriviamo il codice per oggi.Indietro quando iostream era nuovo, molti sviluppatori hanno davvero curato circa la dimensione del codice, che per soddisfare le loro intero programma e dei dati in diverse centinaia di KB).Di conseguenza, molti non vogliono tirare nel "grande" C++ libreria string.Molti nemmeno utilizzare la libreria iostream per le stesse ragioni, la dimensione del codice.

Non abbiamo avuto migliaia di megabyte di RAM da buttare in giro, come facciamo oggi.Noi di solito non hanno funzione di collegamento, quindi siamo stati in balia di sviluppo della biblioteca per l'utilizzo di un sacco di separare i file oggetto o altro tirare in tonnellate di fuori del codice.Tutto questo FUD fatto gli sviluppatori di allontanarsi da std::string.

Allora ho evitato di std::string troppo."Troppo grosso", "chiamato malloc troppo spesso", etc.Stupidamente, utilizzando stack-based buffer per le stringhe, quindi l'aggiunta di tutti i tipi di noioso il codice per assicurarsi che non sovraccarico.

C'è qualche classe in STL, che prende una stringa...Io non la penso così (non riuscivo a trovare qualsiasi nella mia breve ricerca).Quindi probabilmente alcuni di progettazione decisione, che nessuna classe in STL deve essere dipendente da qualsiasi altra classe STL (che non è direttamente necessari per la funzionalità).

Io credo che questo è stato pensato ed è stato fatto per evitare la dipendenza;cioè#include <fstream> non dovrebbe force one per #include <string>.

Per essere onesti, questo mi sembra un insignificante problema.Una domanda migliore sarebbe, perché std::string interfaccia di così grande?

Oggi è possibile risolvere questo problema molto facilmente:aggiungere -std=c++11 per il vostro CFLAGS.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top