Perché ci sono così tante classi di stringhe di fronte a std :: string?

55

Mi sembra che molte più grandi librerie C ++ finiscano per creare il proprio tipo di stringa. Nel codice cliente devi utilizzare quello della libreria ( QString , CString , fbstring ecc., Sono sicuro che chiunque può nominarne alcuni) o continuare a convertire tra il tipo standard e quello usi di libreria (che la maggior parte delle volte coinvolge almeno una copia).

Quindi, c'è una particolare disfunzione o qualcosa di sbagliato su std::string (proprio come la semantica di auto_ptr era cattiva)? È cambiato in C ++ 11?

    
posta Tamás Szelei 05.06.2012 - 16:05
fonte

7 risposte

56

La maggior parte di quelle più grandi librerie C ++ sono state avviate prima che std::string fosse standardizzata. Altri includono funzionalità aggiuntive che sono state standardizzate in ritardo o non ancora standardizzate, come il supporto per UTF-8 e la conversione tra codifiche.

Se quelle librerie fossero implementate oggi, probabilmente sceglierebbero di scrivere funzioni ed iteratori che funzionano su std::string istanze.

    
risposta data 05.06.2012 - 16:08
fonte
38

String è il grande imbarazzo di C ++.

Per i primi 15 anni non fornisci una classe di stringhe - costringi ogni compilatore su ogni piattaforma e ogni utente a crearne uno.

Quindi si crea qualcosa di confuso sul fatto che si supponga che sia un'API di manipolazione delle stringhe completa o solo un contenitore char STL, con alcuni algoritmi che duplicano quelli su un vettore std :: o diversi.

Se un'operazione di stringa ovvia come replace () o mid () coinvolge un tale errore di iterator, è necessario introdurre una nuova parola chiave 'auto' per mantenere l'istruzione su una singola pagina e indurre la maggior parte delle persone a rinunciare l'intera lingua.

E poi hai unicode 'support' e std: wstring che è solo arghh .....

< sbraitare > grazie - mi sento molto meglio ora

    
risposta data 05.06.2012 - 19:26
fonte
32

In realtà ... ci sono diversi problemi con std::string , e sì, si ottiene un po 'meglio in C ++ 11, ma non anticipiamo noi stessi.

QString e CString fanno parte delle librerie vecchie , quindi esistevano prima che il C ++ venisse standardizzato (molto simile al SGI STL). Hanno quindi avuto per creare una classe.

fbstring risponde a problemi di prestazioni molto specifici. Lo standard prescrive un'interfaccia e la complessità algoritmica garantisce minimi, tuttavia è un dettaglio della qualità dell'attuazione se questo finirà per essere veloce o meno. fbstring ha ottimizzazioni specifiche (ad esempio relative allo storage o find più veloce).

Altre preoccupazioni che non sono state evocate qui (en vrac):

  • in C ++ 03 non è obbligatorio che lo storage sia contiguo, rendendo l'interoperabilità con C potenzialmente difficile. C ++ 11 lo risolve.
  • std::string è encoding inconsapevole e non ha codice speciale per UTF-8, è facile memorizzare una stringa UTF-8 in esso e corromperla inavvertitamente
  • L'interfaccia std::string è gonfia , molti metodi potrebbero essere stati implementati come funzioni libere e molti sono duplicati per conformarsi sia a un'interfaccia basata su indice e un'interfaccia basata su iteratore.
risposta data 05.06.2012 - 16:15
fonte
6

Oltre ai motivi pubblicati qui c'è anche un altro - compabilità binaria . I writer delle biblioteche non hanno alcun controllo su quale implementazione di std::string stai usando e se abbia lo stesso layout di memoria del loro.

std::string è un modello, quindi la sua implementazione è presa dalle intestazioni STL locali. Ora immagina di utilizzare localmente una versione STL ottimizzata per le prestazioni, pienamente compatibile con lo standard. Ad esempio, potresti aver scelto di intromettersi il buffer statico in ogni std::string per ridurre il numero di allocazioni dinamiche e di mancate cache. Di conseguenza, il layout della memoria e / o la dimensione dell'implementazione sono diversi da quelli della libreria.

Se solo il layout è diverso, alcune funzioni membro std::string chiamano su istanze passate dalla libreria al client o viceversa potrebbero non riuscire, a seconda di quali membri sono stati spostati.

Se anche la dimensione è diversa, tutti i tipi di libreria con std::string membro avranno dimensioni diverse di quando sono registrati nella libreria e nel codice client. I membri di dati che seguono il membro std::string avranno offset anche spostati, e qualsiasi accesso diretto / accessore in linea chiamato dal client restituirà spazzatura, nonostante "cerchi OK" durante il debug della libreria stessa.

Bottomline - se la libreria e il codice cliente sono compilati di nuovo con diverse std::string versioni, si collegheranno bene, ma potrebbero risultare in alcuni bug sgradevoli e difficili da capire. Se si modifica l'implementazione di std::string , tutte le librerie che espongono i membri da STL devono essere ricompilate in modo che corrispondano al layout std::string del client. E poiché i programmatori vogliono che le loro librerie siano robuste raramente vedrai std::string esposte ovunque.

Per essere onesti, questo vale per tutti i tipi di STL. IIRC non hanno un layout di memoria standarizzato.

    
risposta data 06.06.2012 - 10:41
fonte
6

Ci sono molte risposte alla domanda, ma eccone alcune:

  1. Legacy. Molte librerie di stringhe e classi sono state scritte PRIMA dell'esistenza di std :: string.

  2. Per compatibilità con il codice in C. La libreria std :: string è C ++ dove ci sono altre librerie di stringhe che funzionano con C e C ++.

  3. Per evitare allocazioni dinamiche. La libreria std :: string utilizza l'allocazione dinamica e potrebbe non essere adatta per sistemi incorporati, codice di interrupt o codice in tempo reale o per funzionalità di basso livello.

  4. Modelli. La libreria std :: string è basata su modelli. Fino a poco tempo fa un certo numero di compilatori C ++ aveva un supporto per template poco performante o addirittura buggato. Sfortunatamente, lavoro in un settore che utilizza molti strumenti personalizzati e uno dei nostri toolchain di uno dei principali attori del settore non supporta "ufficialmente" il 100% C ++ (con modelli buggy che sono template e altri).

Ci sono probabilmente anche molti altri validi motivi.

    
risposta data 06.06.2012 - 03:05
fonte
3

Si tratta principalmente di Unicode. Il supporto standard per Unicode è al massimo abissale e ognuno ha le proprie esigenze Unicode. Ad esempio, ICU supporta tutte le funzionalità Unicode che potreste desiderare, dietro l'interfaccia più disgustosa generata automaticamente da Java che potreste immaginare, e se siete su Unix bloccato con UTF-16 potrebbe non essere la vostra idea di un buon tempo.

Inoltre, molte persone hanno bisogno di livelli diversi di supporto Unicode, non tutti hanno bisogno delle complesse API di layout di testo e cose simili. Quindi è facile capire perché esistono numerose classi di stringhe: quella standard è piuttosto succhiata e tutti hanno esigenze diverse da quelle nuove, con nessuno che riesce a creare una singola classe in grado di eseguire un sacco di supporto Unicode multipiattaforma con un'interfaccia piacevole.

Secondo me, questo è principalmente colpa del Comitato C ++ per non aver fornito correttamente il supporto per Unicode - nel 1998 o 2003, forse era comprensibile, ma non in C ++ 11. Speriamo che in C ++ 17 faranno meglio.

    
risposta data 05.06.2012 - 19:20
fonte
-4

È perché ogni programmatore ha qualcosa da dimostrare e sente la necessità di creare la propria classe di corde impressionante e più veloce per la loro unica, fantastica funzione. Di solito è un po 'superfluo e porta a tutti i tipi di conversioni di stringhe aggiuntive nella mia esperienza.

    
risposta data 05.06.2012 - 19:08
fonte

Leggi altre domande sui tag