Qualche gotchas sostituisce const globale [] con constexpr string_view?


17

Il nostro team sta lavorando con una base di codice C ++ di oltre 10 anni e recentemente è passato a un compilatore C ++ 17. Quindi stiamo cercando modi per modernizzare il nostro codice. In una conferenza su YouTube ho sentito il suggerimento di sostituire le const char*stringhe globali constexpr string_view.

Dal momento che const char*nel nostro codice abbiamo ottenuto un certo numero di costanti di stringa globali di questo tipo, voglio chiedermi se ci sono problemi o potenziali problemi di cui dobbiamo essere a conoscenza?

Risposte:


15

Potrebbe essere utile conoscere questi problemi:

  1. std::string_viewnon ha bisogno di essere nullterminato. Quindi, se ne sostituisci alcuni const char*con string_viewe sostituisci la costruzione di una sottostringa precedentemente nullterminata char*con una string_viewvia std::string_view::substr, non puoi passare il puntatore sottostante a un'API che prevede una nullstringa terminata. Esempio (senza UB, ma anche questo è facilmente costruibile):

    void legacy(const char *str) {
       std::printf("%s\n", str);
    }
    
    constexpr std::string_view sv1 = "abcde";
    constexpr std::string_view sv2 = sv1.substr(0, 2); // view on "ab"
    
    legacy(sv2.data()); // Not intended: prints "abcde" 
  2. Mentre puoi implicitamente costruire a std::stringda a const char*, non puoi farlo con a std::string_view. L'idea è che una copia profonda non dovrebbe avvenire sotto la copertina, ma solo quando esplicitamente richiesto. Esempio:

    std::map<std::string, int> m;
    constexpr std::string_view sv = "somekey";
    constexpr const char *old = "somekey";
    
    m[old] = 42; // works as expected
    m[sv] = 42; // fails to compile
    m[std::string(sv)] = 42; // be explicit, this is ok

    A seconda dell'utilizzo esistente delle const char*istanze globali nel progetto, questo comportamento potrebbe richiedere un intervento manuale in vari punti.


quella terminazione diversa da zero è sicuramente un gotcha - auch. Ora ho bisogno di esaminare i nostri SV. Suppongo che faresti std::string(sv).c_str()invece per passare all'API?
darune

@darune Questa è un'opzione, ma poi le ipotesi a vita dell'API dovrebbero essere verificate, giusto ?! Se vai con someLegacyFct(std::string(sv).c_str())e questo backend in qualche modo memorizza il puntatore ...
lubgr

questo è corretto - solo con
quell'assunto a

Il secondo numero è "per fortuna" non sarà un grosso problema per noi. Il nostro framework aziendale ha una propria classe di stringhe (lo so ...), con un const char*costruttore esplicito . Quindi la costruzione esplicita di std::stringfrom string_viewsarebbe semplicemente coerente nel nostro caso.
PixelSupreme
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.