gotchas ใด ๆ ที่แทนที่ global const char [] ด้วย constexpr string_view?


17

ทีมงานของเรากำลังทำงานกับรหัสฐาน C ++ อายุมากกว่า 10 ปีและเพิ่งเปลี่ยนเป็นคอมไพเลอร์ C ++ 17 ดังนั้นเรากำลังมองหาวิธีปรับปรุงรหัสของเราให้ทันสมัย ในการพูดคุยประชุมบน YouTube ผมได้ยินข้อเสนอแนะเพื่อแทนที่สตริงระดับโลกที่มีconst char*constexpr string_view

เนื่องจากเรามีconst char*ค่าคงที่สตริงทั่วโลกจำนวนมากในรหัสของเราฉันต้องการถามว่ามี gotchas หรือปัญหาที่อาจเกิดขึ้นที่เราต้องระวังหรือไม่?

คำตอบ:


15

ปัญหาเหล่านี้อาจคุ้มค่าที่ควรระวัง:

  1. std::string_viewไม่จำเป็นต้องถูกnullทำลาย ดังนั้นหากคุณแทนที่บางส่วนconst char*ด้วยstring_viewและแทนที่การสร้างnullซับchar*สตริงที่string_viewผ่านการทำลายก่อนหน้านี้ด้วยการผ่านstd::string_view::substrคุณจะไม่สามารถส่งตัวชี้พื้นฐานไปยัง API ที่คาดว่าจะเป็นnullสตริง -terminated ตัวอย่าง (ไม่มี UB แต่สามารถสร้างได้ง่ายเช่นกัน):

    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. ในขณะที่คุณปริยายสามารถสร้างstd::stringจากคุณไม่สามารถทำเช่นนั้นด้วยconst char* std::string_viewความคิดคือว่าสำเนาลึกไม่ควรเกิดขึ้นภายใต้ครอบคลุม แต่เฉพาะเมื่อมีการร้องขออย่างชัดเจน ตัวอย่าง:

    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*อินสแตนซ์ทั่วโลกที่มีอยู่ในโครงการของคุณลักษณะการทำงานนี้อาจต้องการการแทรกแซงด้วยตนเองในหลาย ๆ ที่


การเลิกจ้างที่ไม่เป็นศูนย์นั้นแน่นอนว่า gotcha - auch ตอนนี้ฉันต้องผ่าน SVs ของเรา ฉันคิดว่าคุณจะทำstd::string(sv).c_str()แทนการส่งผ่าน API หรือไม่
darune

@darune นั่นเป็นตัวเลือก แต่หลังจากนั้นควรตรวจสอบสมมติฐานอายุการใช้งานของ API ใช่มั้ย! ถ้าคุณไปกับsomeLegacyFct(std::string(sv).c_str())แบ็กเอนด์นี้จะเก็บพอยน์เตอร์ไว้ ...
lubgr

ที่ถูกต้อง - เฉพาะกับสมมติฐานที่อายุการใช้งาน
darune

ประเด็นที่สองคือ "โชคดี" ที่จะไม่เป็นเรื่องใหญ่สำหรับเรา เฟรมเวิร์ก บริษัท ของเรามีคลาสสตริงเป็นของตัวเอง (ฉันรู้ว่า ... ) พร้อมตัวconst char*สร้างที่ชัดเจน ดังนั้นการสร้างที่ชัดเจนstd::stringจากในstring_viewนั้นก็จะสอดคล้องกันในกรณีของเรา
PixelSupreme
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.