首页 > 解决方案 > 任何用 constexpr string_view 替换全局 const char[] 的陷阱?

问题描述

我们的团队正在使用 10 多年的 C++ 代码库,最近切换到 C++17 编译器。所以我们正在寻找使我们的代码现代化的方法。在 YouTube 上的一次会议演讲中,我听到了将const char*全局字符串替换为constexpr string_view.

由于我们的代码中有很多这样的const char*全局字符串常量,我想问一下是否有任何我们需要注意的问题或潜在问题?

标签: c++c++17constexprstring-view

解决方案


这些问题可能值得关注:

  1. std::string_view不需要被null终止。因此,如果您将 some const char*bystring_view替换为 via 并将先前null终止char*的子字符串的构造替换为string_viewvia std::string_view::substr,则无法将底层指针传递给需要 -null终止字符串的 API。示例(没有 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虽然你可以从 a隐式构造 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*项目中全局实例的现有使用情况,此行为可能需要在不同位置进行手动干预。


推荐阅读