在这种情况下,使用 string_view 会导致不必要的字符串复制吗?
Does using string_view lead to an unnecessary string copy in this scenario?
我想要做的是让我的 class 在构建期间接受一个字符串。我读到 string_view
是 const string&
的替代品,所以我很自然地写了一个这样的构造函数。这允许我接受 C++ 和 C 字符串。
Url::Url(boost::string_view raw_url)
: url_(static_cast<std::string>(raw_url)) {
这里可能存在的问题是,当传递一个右值时,有一个不必要的复制而不是一个移动。是制作另一个采用 string&&
的构造函数的解决方案吗?这里的最佳做法是什么?
注意:我会考虑 std::string_view
来写答案,但 boost::string_view
应该是相似的。
I read that string_view was a replacement for const string&
了解为什么首先添加 std::string_view
的原因很有用。
const string&
有什么问题?
如果你传递一个std::string
对象而你对std::string_view
没有任何收获,那肯定是有效的。但是现在假设您正在传递一个包含大字符串的 char*
。在这种情况下,将创建一个临时 std::string
对象(并且将复制该 char*
引用的整个字符串),以便函数接收 std::string
。那是 std::string_view
闪耀的时候。如果将 char*
或 std::string
(或任何可以转换为 std::string_view
的东西)传递给接受 std::string_view
的函数(按值,不需要接受 std::string_view
通过引用)然后创建的新 std::string_view
对象非常便宜,因为它只是 "a view" 并且它不复制底层字符串。
但你的情况不同。由于你无论如何都在复制字符串,那么你的函数应该只接受一个字符串by value并将字符串移动到函数内部。比如
Url::Url(std::string raw_url)
: url_(std::move(raw_url)) {
还有一个clang-tidy warning告诉你这个
优点是,如果你的函数的用户传递了一个左值,你就制作了一个副本(无论如何你都需要它)和一个移动,但是如果他们传递了一个右值,那么就没有副本,只有一个移动。
我想要做的是让我的 class 在构建期间接受一个字符串。我读到 string_view
是 const string&
的替代品,所以我很自然地写了一个这样的构造函数。这允许我接受 C++ 和 C 字符串。
Url::Url(boost::string_view raw_url)
: url_(static_cast<std::string>(raw_url)) {
这里可能存在的问题是,当传递一个右值时,有一个不必要的复制而不是一个移动。是制作另一个采用 string&&
的构造函数的解决方案吗?这里的最佳做法是什么?
注意:我会考虑 std::string_view
来写答案,但 boost::string_view
应该是相似的。
I read that string_view was a replacement for const string&
了解为什么首先添加 std::string_view
的原因很有用。
const string&
有什么问题?
如果你传递一个std::string
对象而你对std::string_view
没有任何收获,那肯定是有效的。但是现在假设您正在传递一个包含大字符串的 char*
。在这种情况下,将创建一个临时 std::string
对象(并且将复制该 char*
引用的整个字符串),以便函数接收 std::string
。那是 std::string_view
闪耀的时候。如果将 char*
或 std::string
(或任何可以转换为 std::string_view
的东西)传递给接受 std::string_view
的函数(按值,不需要接受 std::string_view
通过引用)然后创建的新 std::string_view
对象非常便宜,因为它只是 "a view" 并且它不复制底层字符串。
但你的情况不同。由于你无论如何都在复制字符串,那么你的函数应该只接受一个字符串by value并将字符串移动到函数内部。比如
Url::Url(std::string raw_url)
: url_(std::move(raw_url)) {
还有一个clang-tidy warning告诉你这个
优点是,如果你的函数的用户传递了一个左值,你就制作了一个副本(无论如何你都需要它)和一个移动,但是如果他们传递了一个右值,那么就没有副本,只有一个移动。