Adakah yang mengganti global const char [] dengan constexpr string_view?

17

Tim kami bekerja dengan basis kode C ++ 10+ tahun dan baru-baru ini beralih ke kompiler C ++ 17. Jadi kami mencari cara untuk memodernisasi kode kami. Dalam ceramah konferensi di YouTube saya mendengar saran, untuk menggantikan const char*string global constexpr string_view.

Karena kita punya cukup banyak const char*konstanta string global dalam kode kita, saya ingin bertanya apakah ada masalah atau masalah potensial yang perlu kita ketahui?

PixelSupreme
sumber

Jawaban:

15

Masalah-masalah ini mungkin perlu diperhatikan:

  1. std::string_viewtidak perlu nulldimusnahkan. Jadi, jika Anda mengganti beberapa const char*dengan string_viewdan mengganti konstruksi substring yang sebelumnya telah nulldimusnahkan char*oleh string_viewvia std::string_view::substr, Anda tidak bisa meneruskan pointer yang mendasari ke API yang mengharapkan nullstring -minmin. Contoh (tanpa UB, tapi itu juga mudah dibangun):

    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. Meskipun Anda secara implisit dapat membangun std::stringdari const char*, Anda tidak dapat melakukannya dengan a std::string_view. Idenya adalah bahwa salinan yang dalam tidak boleh terjadi di bawah sampul, tetapi hanya ketika diminta secara eksplisit. Contoh:

    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

    Bergantung pada penggunaan const char*instance global yang ada dalam proyek Anda, perilaku ini mungkin memerlukan intervensi manual di berbagai tempat.

lubgr
sumber
bahwa pemutusan yang tidak nol adalah suatu gotcha - auch. Sekarang saya harus membaca SV. Saya kira Anda akan melakukan std::string(sv).c_str()sebaliknya untuk meneruskan ke API?
darune
@ Darune Itu pilihan, tapi kemudian asumsi API seumur hidup harus diperiksa, kan ?! Jika Anda pergi dengan someLegacyFct(std::string(sv).c_str())dan backend ini entah bagaimana menyimpan pointer ...
lubgr
itu benar - hanya dengan asumsi seumur hidup
darune
Masalah kedua adalah "untungnya" tidak akan menjadi masalah besar bagi kita. Kerangka kerja perusahaan kami memiliki kelas string sendiri (saya tahu ...), dengan const char*konstruktor eksplisit . Jadi konstruksi eksplisit std::stringdari string_viewhanya akan konsisten dalam kasus kami.
PixelSupreme