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?

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.


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.