web-dev-qa-db-fra.com

Y a-t-il des accrochages remplaçant le const const char [] par constexpr string_view?

Notre équipe travaille avec une base de code C++ de 10 ans et plus et est récemment passée à un compilateur C++ 17. Nous recherchons donc des moyens de moderniser notre code. Lors d'une conférence sur YouTube, j'ai entendu la suggestion de remplacer const char* chaînes globales avec constexpr string_view.

Puisque nous avons obtenu un bon nombre de ces const char* constantes de chaînes globales dans notre code, je veux demander s'il y a des problèmes ou des problèmes potentiels dont nous devons être conscients?

17
PixelSupreme

Ces problèmes méritent d'être pris en compte:

  1. std::string_view n'a pas besoin d'être null - terminé. Donc, si vous remplacez certains const char* par string_view et remplacer la construction d'un ancien null - terminé char* sous-chaîne par un string_view via std::string_view::substr, vous ne pouvez pas passer le pointeur sous-jacent à une API qui attend une chaîne terminée par null. Exemple (sans UB, mais qui est également facilement constructible):

    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. Bien que vous puissiez implicitement construire un std::string de const char*, vous ne pouvez pas le faire avec un std::string_view. L'idée est qu'une copie complète ne doit pas se produire sous la couverture, mais uniquement lorsqu'elle est explicitement demandée. Exemple:

    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
    

    En fonction de l'utilisation actuelle du global const char* instances dans votre projet, ce comportement peut nécessiter une intervention manuelle à divers endroits.

14
lubgr