2013-08-26 14 views
8

Mentre sfiorando il progetto di C++ 14/C++ 1A (n3690) ho notato che l'introduzione dei basic_string suffissi litertal nella sezione §21.7:I letterali basic_string sono più veloci o gestiti meglio in fase di compilazione?

inline namespace literals { 
inline namespace string_literals { 
    // 21.7, suffix for basic_string literals: 
    string operator "" s(const char *str, size_t len); 
    u16string operator "" s(const char16_t *str, size_t len); 
    u32string operator "" s(const char32_t *str, size_t len); 
    wstring operator "" s(const wchar_t *str, size_t len); 
} 
} 

Le mie domande sono:

  • C'è una possibilità di essere più veloce in fase di esecuzione con i valori letterali basic_string?
  • La mia implementazione "ingenua" è totalmente sbagliata?
  • Il layout dei dati nella ROM può essere diverso con i valori letterali basic_string o qualsiasi altra differenza in fase di compilazione rispetto al tempo di esecuzione?

Sfondo

So che questo permette l'uso diretto di stringhe letterali come questo:

std::string s1 = "A fabulous string"s; 

void sfunc(std::string arg); 

int main() { 
    sfunc("argument"s); 
} 

Ma qual è il vantaggio di cui sopra basandosi su costruttore conversionestring(const char*)?

Il codice "vecchio" apparirebbe:

std::string s1 = "A fabulous string"; // c'tor string(const char*) 

void sfunc(std::string arg); 

int main() { 
    sfunc("argument"); // auto-conversion via same c'tor 
} 

Per quanto posso vedere l'attuazione di operator "" s() sarebbe sostanzialmente simile a questa:

std::string operator "" s(const char* lit, size_t sz) { 
    return std::string(lit, sz); 
} 

Così, proprio l'uso del lo stesso c'tor. E la mia ipotesi è, che deve essere fatto in fase di esecuzione, mi sbaglio?

Edit: Come Nicol Bolas sottolineato correttamente seguito il mio esempio non non usano lo stesso costruttore, ma quello con la lunghezza supplementare - che è molto utile per la costruzione, ovviamente. Questo mi lascia la domanda: è meglio per il compilatore inserire letterali stringa in ROM o qualcosa di simile in fase di compilazione?

risposta

6
  • C'è la possibilità di essere più veloce a run-time con letterali basic_string?

Come già detto, la lunghezza della stringa è noto e automaticamente passato al costruttore.

  • La mia implementazione "ingenua" è totalmente sbagliata?

No, è corretto.

  • Può il layout dei dati in ROM essere diverso con basic_string letterali, o qualsiasi altra differenza al momento della compilazione rispetto al run-time?

Probabilmente no, perché il relativo costruttore basic_string non è constexpr quindi non sarà eleggibile per l'inizializzazione statica, quindi probabilmente non può essere messo in ROM e deve essere fatto a run-time.

4

Quindi, solo l'uso dello stesso lettore.

OK, vediamo come sarebbe guardare:

string fromLit = "A fabulous string"s; 
string fromBare = string("A fabulous string"); 

vedere nulla manca in fromBare? Mi permetta di scriverlo per voi:

string fromBare = string("A fabulous string"/*, NOTHING*/); 

Sì, non si può ottenere il lunghezza della stringa, senza ... ottenere la sua lunghezza. Il che significa che fromBare dovrà scorrere il letterale per trovare il carattere \0. In fase di esecuzione. fromLit no; il compilatore fornisce la lunghezza della stringa come parametro determinato in fase di compilazione. Qualsiasi compilatore che valga la pena di usare sarà sufficiente inserire la lunghezza nel codice eseguibile.

E anche se quello non era il caso, è ancora meglio per altri motivi. Considerate questo:

void SomeFunc(const std::string &); 
void SomeFunc(const char *); 

SomeFunc("Literal"); 
SomeFunc("Literal"s); 
SomeFunc(std::string("Literal")); 

Gli ultimi due fanno la stessa cosa (meno il punto che ho fatto prima), ma uno di loro è molto più più breve. Anche se si impiega using std::string (o stupidamente using namespace std;), il secondo è ancora più corto. Eppure è chiaro esattamente cosa sta succedendo.

+0

Ottimo punto! Avere la lunghezza è un vantaggio, abbastanza sicuro. – towi

+0

Per quanto riguarda le prestazioni, dubito che i letterali stringa daranno una spinta all'utilizzo di un const statico: 'static std :: string lit (" Literal ");'; potrebbero anche essere significativamente più lenti. Dover inventare un nome e dichiarare una variabile extra è un dolore, tuttavia, e le stringhe letterali sono definitivamente un miglioramento su queste basi. –

1

Fornisce più sicurezza in fase di compilazione.

consideri How do you construct a std::string with an embedded null?

L'unico modo per costruire un std::string da una stringa letterale che contiene un carattere nullo è quello di specificare la dimensione della stringa letterale (soggetto a errori), utilizzare initializer_list sintassi (dettagliata) o fare una sorta di loop con più chiamate a push_back (ancora più dettagliato). Tuttavia, con il costruttore letterale, la dimensione viene automaticamente inoltrata per te, rimuovendo una possibile fonte di errore.

+0

Punto interessante, ma piuttosto raro. String letterali contenenti '\ 0' - succede, ma di rado. E poiché l'autore ha il controllo su stringhe letterali, introduce solo un piccolo problema. +1 senza dubbio, per l'aspetto interessante. – towi

Problemi correlati