在这种情况下,使用 string_view 是否会导致不必要的字符串复制?

Does using string_view lead to an unnecessary string copy in this scenario?

本文关键字:不必要 字符串 复制 是否 这种情况下 使用 string view      更新时间:2023-10-16

我想做的是让我的类在构造过程中接受一个字符串。我读到string_viewconst string&的替代品,所以我很自然地写了一个这样的构造函数。这允许我接受 c++ 和 c 字符串。

Url::Url(boost::string_view raw_url)
: url_(static_cast<std::string>(raw_url)) {

这里可能存在的问题是,当传递右值时,存在不必要的副本而不是移动。解决方案是制作另一个需要string&&的构造函数吗?这里的最佳实践是什么?

注意:我会写出std::string_view答案,但boost::string_view应该是相似的。


我读到string_view是 const 字符串的替代品

了解最初添加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对象非常便宜,因为它只是"视图",并且不会复制基础字符串。


但你的情况不同。由于您无论如何都要复制字符串,因此您的函数应该只按值接受字符串并将字符串移动到函数内。诸如此类的东西

Url::Url(std::string raw_url)
: url_(std::move(raw_url)) {

甚至还有一个叮叮当当的警告告诉你这一点。

优点是,如果你的函数的用户传递了一个左值,你就会做一个副本(无论如何你都需要它(和一个移动,但如果他们传递了一个右值,那么就没有副本,只有一个移动。