我理解使用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&
替换为参数传递?
答案 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
,因此分配两次。