考虑以下代码:
void Log(std::string_view msg,
std::source_location const& loc = std::source_location::current()) {
// PERFORMANCE PENALTY!
auto const n = std::strlen(loc.file_name());
auto s = ""s;
s.resize(msg.size() + n);
std::memcpy(&s[0], msg.data(), msg.size());
std::memcpy(&s[msg.size()], loc.file_name(), n);
s[msg.size() + n] = 0; // ensure to be null-terminated
// sendToRemoteMachine(s);
}
显然,如果
std::source_location::file_name
返回 std::string_view
,就可以轻松避免性能损失。
为什么 std::source_location 不提供长度以避免 C++20 中的性能损失?
更新
C++ 没有代表以下所有内容的类型:
std::string
同时具有 2 和 3,但不具有 1。 string_view
具有 1 和 2,但不保证在类型级别为 3。 char const*
有 1,人们普遍期望他们使用 3,但他们不携带 2。
是的,#3 实际上非常重要。您的示例想要将字符串传递给需要大小字符串的 API;这就是你计算大小的原因。其他人将拥有需要 NTBS 的 API。对于他们来说,基于
string_view
的 API 现在要求他们将调整大小的字符串复制到 NTBS 中。这是一个 O(N) 操作。
除非您有一种类型可以传达所有这 3 种情况,否则你们中的一个人将必须执行 O(N) 操作。
是的,从技术上讲,
string_view
可以指向 NTBS。但在类型级别,如果您收到一个 string_view
,您不会 知道 它指向 NTBS。这将是生成它的函数的保证,而不是类型本身的保证。所以这是对该类型的不恰当使用。