std::string_view
s 是对内存中其他地方的字符串的引用。但与好的(或坏的)旧 C 不同char *
,std::string_view
s 有一个指针和一个大小。这就是为什么它们可以引用其他字符串的特定部分,这就是为什么对 sremove_prefix()
进行remove_suffix()
有意义的操作string_view
。
但是,您不需要 for 的assign()
方法std::string_view
,因为这与赋值运算符没有什么不同。std::string
有一种assign()
方法可以处理很多情况,赋值运算符std::string
无法处理,因为它不能接受多个参数。几个例子:
std::string A { "This is a somewhat lengthy string" };
std::list<char> L { '1', 'A', 'Z' };
std::string B;
B.assign(80, ' '); // Create an empty line of spaces
B.assign(A, 10, 8); // Copy out a substring of another string
B.assign(L.begin(), L.end()); // Assign from an STL container
在这三种情况中,只有中间一种对 有意义std::string_view
。第一种和最后一种情况都需要分配一个字符串,这是std::string_view
不能做的。
然而,中间的情况可以很容易地通过使用来实现std::string_view::substr()
。例如:
std::string A { "This is a somewhat lengthy string" };
std::string_view V { "Directly pointing to A C string" };
std::string_view B;
B = std::string_view{A}.substr(10, 8); // Reference substring of A
B = B.substr(0, 4); // Further shorten the reference
B = V.substr(0, 8); // Reassign with another reference
B = B.substr(0, 0); // "Clear" the string_view
因此,clear()
和assign()
to astd::string_view
都可以使用赋值运算符来完成。这不适用于std::string
: 中间分配用来自 的数据B.assign(A, 10, 8);
覆盖已经分配B
的数据A
。使用赋值运算符 like 的解决方案B = A.substr(10, 8);
将导致std::string
通过substr()
调用创建一个临时对象,然后内部释放B
之前分配的内存。这通常效率不高,这就是将子字符串分配方法添加到std::string()
. 另一方面,std::string_view::substr()
不需要复制任何字符串数据,因此B = std::string_view{A}.substr(10, 8);
可以轻松优化分配!
请注意,以下代码是一个错误,并且会在堆上留下对临时子字符串的悬空引用:
std::string A { "This is a somewhat lengthy string" };
std::string_view V { A.substr(10, 8) };
因此,如果您需要将 a 设置std::string_view
为字符串的子字符串,请始终转换为std::string_view
第一个(通过std::string_view(string)
),然后substr()
在std::string_view
. 当然,请确保原始string
文件比新生成的文件更有效std::string_view
,否则您最终会得到悬空引用。