有没有用 constexpr string_view 替换 global const char[] 的问题?
Any gotchas replacing global const char[] with constexpr string_view?
我们的团队正在使用 10 多年的 C++ 代码库,最近切换到 C++17 编译器。因此,我们正在寻找使我们的代码现代化的方法。在 YouTube 上的一次会议演讲中,我听到了将 const char*
全局字符串替换为 constexpr string_view
的建议。
由于我们的代码中有很多这样的 const char*
全局字符串常量,我想问一下是否有任何陷阱或我们需要注意的潜在问题?
这些问题可能值得注意:
std::string_view
不需要 null
终止。因此,如果您将某些 const char*
替换为 string_view
,并通过 std::string_view::substr
将先前以 null
终止的 char*
子字符串的构造替换为 string_view
,您不能将基础指针传递给需要 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"
虽然可以从 const char*
隐式构造 std::string
,但不能使用 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*
实例的现有使用情况,此行为可能需要在不同位置进行手动干预。
我们的团队正在使用 10 多年的 C++ 代码库,最近切换到 C++17 编译器。因此,我们正在寻找使我们的代码现代化的方法。在 YouTube 上的一次会议演讲中,我听到了将 const char*
全局字符串替换为 constexpr string_view
的建议。
由于我们的代码中有很多这样的 const char*
全局字符串常量,我想问一下是否有任何陷阱或我们需要注意的潜在问题?
这些问题可能值得注意:
std::string_view
不需要null
终止。因此,如果您将某些const char*
替换为string_view
,并通过std::string_view::substr
将先前以null
终止的char*
子字符串的构造替换为string_view
,您不能将基础指针传递给需要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"
虽然可以从
const char*
隐式构造std::string
,但不能使用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*
实例的现有使用情况,此行为可能需要在不同位置进行手动干预。