Будь-які проблеми, які замінюють глобальний const char [] на constexpr string_view?


17

Наша команда працює з базою кодів C ++ для 10+ років і нещодавно перейшла на компілятор C ++ 17. Тож ми шукаємо шляхи модернізації нашого коду. У конференції на YouTube я почув пропозицію замінити const char*глобальні рядки на constexpr string_view.

Оскільки const char*в нашому коді є досить багато таких глобальних струнних констант, я хочу запитати, чи є якісь проблеми чи можливі проблеми, про які нам потрібно знати?

Відповіді:


15

Ці питання, можливо, варто знати:

  1. std::string_viewне потрібно піддаватися nullприпиненню. Так що, якщо замінити деякі const char*на string_viewі замінити конструкцію раніше null-завершённих char*подстрок по з string_viewдопомогою std::string_view::substr, ви не можете передати покажчик , що лежить на API, що очікує null-завершённую рядок. Приклад (без 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. Хоча ви можете неявно побудувати a std::stringз a const char*, ви не можете цього зробити з a 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. Тепер мені потрібно пройти наші СВ. Я припускаю, що ви зробили б std::string(sv).c_str()замість цього перейти до API?
дарун

@darune Це варіант, але тоді життєві припущення API слід перевірити, правда ?! Якщо ви підете someLegacyFct(std::string(sv).c_str())і цей бекенд якось зберігає вказівник ...
лубгр

що правильно - тільки при цьому довічне припущенні
darune

Друге питання "на щастя" не буде для нас великою справою. У нашій компанії є власний клас струн (я знаю ...), з чітким const char*конструктором. Тож явна побудова std::stringз string_viewпросто би відповідала в нашому випадку.
PixelSupreme
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.