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?
Ces problèmes méritent d'être pris en compte:
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"
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.