我什么时候能通过const& std :: string而不是std :: string_view?

时间:2016-09-19 02:12:45

标签: c++ string stl parameter-passing string-view

我理解使用std::string_view的动机; 它可以帮助避免函数参数中的不必要的分配。

例如:
以下程序将从字符串文字创建std::string 这会导致不希望的动态分配,因为我们只对观察字符感兴趣。

#include <iostream>

void* operator new(std::size_t n)
{
    std::cout << "[allocating " << n << " bytes]\n";
    return malloc(n);
}

void observe_string(std::string const& str){}

int main(){
  observe_string("hello world"); //prints [allocating 36 bytes]
}

使用string_view将解决问题:

#include <iostream>
#include <experimental/string_view>

void* operator new(std::size_t n)
{
    std::cout << "[allocating " << n << " bytes]\n";
    return malloc(n);
}

void observe_string(std::experimental::string_view const& str){
}

int main(){
  observe_string("hello world"); //prints nothing
}

这给我留下了一个问题 我什么时候可以选择std :: string by const&amp;而不是string_view的函数参数?

查看std::string_view的界面,看起来我可以替换std::string传递的const&的所有实例。这有什么反例吗? std::string_view是否意味着将std::string const&替换为参数传递?

4 个答案:

答案 0 :(得分:8)

  

我什么时候会为std::string而不是const&选择string_view作为函数参数?

是否需要以空字符结尾的字符串?如果是这样,那么您应该使用std::string const&来为您提供保证。 string_view没有 - 它只是const char的范围。

如果您需要以空字符结尾的字符串,并且您不需要获取数据的所有权,那么您应该使用string_view。如果您确实需要获取数据的所有权,那么string值可能优于string_view

答案 1 :(得分:2)

Andrei Alexandrescu曾经说过,&#34;没有工作比某些工作更好&#34; 。所以你应该在这种情况下使用const std::string&。因为std::string_view仍然涉及一些工作(复制一对指针和长度)。

当然,const引用可能仍然需要复制指针的成本;这几乎相当于std::string_view将要做的事情。但是还有std::string_view的另外一项工作,它也会复制长度。

这是理论上的,但在实践中,首选基准来推断效果

答案 2 :(得分:2)

接受const std::string&而不是string_view的一个可能原因是,您希望存储对稍后可以更改的字符串对象的引用。

如果您接受并存储string_view,则在string内部缓冲区重新分配时,它可能会变为无效。

如果您接受并存储对字符串本身的引用,那么您就不会遇到该问题,只要该对象处于活动状态(您可能希望删除r值引用过载,以避免临时问题)。

答案 3 :(得分:0)

这不是您要求的,但有时您需要按值<{1}} 而不是std::string出于性能原因。如果您需要在检查字符串之前修改字符串,则会出现这种情况:

std::string_view

无论如何,你需要一个可变的字符串,所以你可以将它声明为函数参数。如果您将其更改为bool matches(std::string s) { make_upper_case(s); return lib::test_if_matches(s); } ,并且某人将std::string_view传递给std::string,则您首先会将matches()转换为string,然后string_view }到string_view,因此分配两次。