Любые ошибки заменить глобальный const char [] на constexpr string_view?

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

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

Ответы

Ответ 1

Об этих проблемах стоит знать:

  1. std::string_view не обязательно должен быть null -terminated. Таким образом, если вы замените часть const char* на string_view и замените конструкцию подстроки null -terminated 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* в вашем проекте, это может потребовать ручного вмешательства в различных местах.