Bất kỳ vấn đề nào thay thế const char toàn cầu [] bằng constexpr string_view?


17

Nhóm của chúng tôi đang làm việc với cơ sở mã C ++ hơn 10 năm tuổi và gần đây đã chuyển sang trình biên dịch C ++ 17. Vì vậy, chúng tôi đang tìm cách để hiện đại hóa mã của chúng tôi. Trong một cuộc hội thảo trên YouTube, tôi đã nghe đề xuất này, để thay thế const char*các chuỗi toàn cầu bằng constexpr string_view.

Vì chúng tôi có khá nhiều const char*hằng số chuỗi toàn cầu như vậy trong mã của chúng tôi, tôi muốn hỏi liệu có bất kỳ vấn đề hay vấn đề tiềm năng nào mà chúng tôi cần phải biết không?

Câu trả lời:


15

Những vấn đề này có thể đáng được lưu ý:

  1. std::string_viewkhông cần phải bị nullhủy diệt Vì vậy, nếu bạn thay thế một số const char*bằng string_viewvà thay thế việc xây dựng một chuỗi con đã bị nullhủy trước đó char*bằng một string_viewthông qua std::string_view::substr, bạn không thể chuyển con trỏ bên dưới sang một API mong đợi một nullchuỗi bị hủy. Ví dụ (không có UB, nhưng cũng có thể dễ dàng xây dựng):

    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. Trong khi bạn có thể ngầm định xây dựng một std::stringtừ a const char*, bạn không thể làm điều đó với a std::string_view. Ý tưởng là một bản sao sâu không nên xảy ra dưới bìa, nhưng chỉ khi được yêu cầu rõ ràng. Thí dụ:

    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

    Tùy thuộc vào việc sử dụng hiện tại của các phiên bản toàn cầu const char*trong dự án của bạn, hành vi này có thể yêu cầu can thiệp thủ công ở nhiều nơi khác nhau.


rằng chấm dứt khác không chắc chắn là một gotcha - auch. Bây giờ tôi cần phải đi qua các SV của chúng tôi. Tôi cho rằng bạn sẽ làm std::string(sv).c_str()thay vì chuyển qua API?
darune

@darune Đó là một tùy chọn, nhưng sau đó phải kiểm tra các giả định trọn đời của API, đúng không?! Nếu bạn đi cùng someLegacyFct(std::string(sv).c_str())và phần phụ trợ này bằng cách nào đó lưu trữ con trỏ ...
Lubgr

điều đó là chính xác - chỉ với giả định trọn đời đó
darune

Vấn đề thứ hai là "may mắn" sẽ không phải là vấn đề lớn đối với chúng tôi. Khung công ty của chúng tôi có lớp chuỗi riêng (tôi biết ...), với một hàm tạo rõ ràng const char*. Vì vậy, xây dựng rõ ràng std::stringtừ string_viewsẽ chỉ là nhất quán trong trường hợp của chúng tôi.
PixelSup tối
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.