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

Tho*_*mas 3 c++ string-view

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

Url::Url(boost::string_view raw_url)
    : url_(static_cast<std::string>(raw_url)) {
Run Code Online (Sandbox Code Playgroud)

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

dar*_*amo 5

注意:我会考虑写答案std::string_view,但boost::string_view应该类似。


我读到 string_view 是 const string& 的替代品

std::string_view首先了解添加的原因很有用。

有什么问题const string&吗?

如果你传递一个std::string对象并且你没有从 中获得任何东西,那么它肯定是有效的std::string_view。但假设现在您正在传递一个char*包含大字符串的字符串。std::string在这种情况下,将创建一个临时对象(并且char*将复制该对象引用的整个字符串),以便该函数接收一个std::string. 那就是std::string_view闪耀的时候。如果将 achar*或 a std::string(或任何可以转换为)传递给接受(按值,不需要按引用接受 a )的std::string_view函数,那么创建的新对象非常便宜,因为它只是“一个视图”并且它不会复制底层字符串。std::string_viewstd::string_viewstd::string_view


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

Url::Url(std::string raw_url)
    : url_(std::move(raw_url)) {
Run Code Online (Sandbox Code Playgroud)

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

优点是,如果您的函数的用户传递一个左值,您将创建一个副本(无论如何您都需要它)并进行移动,但如果他们传递一个右值,则没有副本而只有移动。