Любые ошибки заменить глобальный const char [] на constexpr string_view? - PullRequest
16 голосов
/ 08 октября 2019

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

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

1 Ответ

12 голосов
/ 08 октября 2019

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

  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. Хотя вы можете неявно построить 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* экземпляров в вашем проекте, это поведение может потребовать ручного вмешательства в различных местах.

...