Global const char [] yerine constexpr string_view değiştiren var mı?


17

Ekibimiz 10+ yaş C ++ kod tabanı ile çalışıyor ve yakın zamanda C ++ 17 derleyicisine geçti. Bu yüzden kodumuzu modernize etmenin yollarını arıyoruz. YouTube'daki bir konferans görüşmesinde, const char*küresel dizeleri değiştirmek için öneriyi duydum constexpr string_view.

Kodumuzda çok sayıda const char*küresel dize sabitine sahip olduğumuzdan, bilmemiz gereken herhangi bir gotcha veya potansiyel sorun olup olmadığını sormak isterim?

Yanıtlar:


15

Bu sorunların farkında olmaya değer olabilir:

  1. std::string_view- nullSonlandırılması gerekmez . Bazılarını const char*by string_viewile değiştirirseniz ve önceden nullsonlandırılmış bir char*alt dizenin yapısını bir string_viewvia ile değiştirirseniz std::string_view::substr, temel işaretçiyi nullsonlandırılmış bir dize bekleyen bir API'ye geçiremezsiniz . Örnek (UB olmadan, ancak bu da kolayca oluşturulabilir):

    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. Örtük olarak a ' std::stringdan yapılandırabilirken const char*, bunu a ile yapamazsınız std::string_view. Fikir, kapağın altında derin bir kopya olmamalı, sadece açıkça talep edildiğinde gerçekleşmelidir. Misal:

    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

    const char*Projenizdeki global örneklerin mevcut kullanımına bağlı olarak , bu davranış çeşitli yerlerde manuel müdahale gerektirebilir.


sıfır olmayan sonlandırma kesinlikle bir gotcha - auch. Şimdi SV'lerimizden geçmem gerekiyor. Bunun std::string(sv).c_str()yerine API'ye geçmek için yapardınız ?
darune

@darune Bu bir seçenek, ancak API'nın ömür boyu varsayımları kontrol edilmelidir, değil mi ?! someLegacyFct(std::string(sv).c_str())
İle

bu doğru - sadece bu ömür boyu varsayımla
darune

İkinci konu "neyse ki" bizim için büyük bir sorun olmayacak. Şirketimizin çerçevesi, açık bir const char*kurucu ile kendi dize sınıfına (biliyorum ...) sahiptir . Yani açık inşaat std::stringdan string_viewsadece bizim durumumuzda tutarlı olacaktır.
PixelSupreme
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.