不落辰

知不可乎骤得,托遗响于悲风

0%

c++_string_view

string_view : {data_pointer , data_len}
不拥有数据、只读
解决在只需读str时 还会拷贝str造成的开销 ; 提高效率.
可用string_view代替const string &作为形参

基本参考一篇挺好的string_view科普.

总结如下

string_view

原因

  • 为什么要有string_view ? 提高性能. 为什么提高性能 ? 有const string &还不够吗 ?
    • const string &问题如下.
    • 对于形参为const string&的,此时的情况必然是传递的数据为只读.
        1. 使用&当然是为了避免拷贝, 可是对于要传递给const & , 只有当实参类型相同 , 即为string时, 才不会发生拷贝.
      • 如果实参 字符串字面值(“sss”)、字符数组(char [])、字符串指针(char *) 的传递给 const string& —> 仍要数据拷贝
        • 实参与string类型不同 , 则需要拷贝生成个string临时对象,然后const string &指向这个临时对象. 见(C++ Primer)
        1. 同时string的substr效率为O(n),耗费性能.
        • O(n) : 因为substr会生成新的子串
        • 我们本意很可能并不是要改变原字符串,实际上返回源字符串本身的一部分即可

特点

  • string_view
    • 组成 : {data_pointer , data_len}.
    • string_view本身并不持有数据,只是有个指向数据的指针罢了. 所以注意string_view可能指向一个已经失效的str
    • 只读data,不可修改data
    • 构造:除默认构造和拷贝构造外,还有
      • constexpr string_view(const CharT* s, size_type count);
      • constexpr string_view(const CharT* s);
      • string_view foo(string(“abc”))
        • a. string(“abc”)转换为string_view对象
        • b. string_view对象拷贝构造
    • 自定义字面量 : sv做后缀 , 将串中的\0视作字符而非null
      1
      2
      3
      4
      5
      6
      7
      using namespace std::literals;
      std::string_view s1 = "abc\0\0def";
      std::string_view s2 = "abc\0\0def"sv;
      std::cout << "s1: " << s1.size() << " \"" << s1 << "\"\n";
      std::cout << "s2: " << s2.size() << " \"" << s2 << "\"\n";
      s1: 3 "abc"
      s2: 8 "abc^@^@def"
    • 好处
        1. 我们可以使用string_view 代替 const string & 作为形参. 效率更高. 无论实参是 “sss” , char[] , 还是 char * , 还是string , 都只需要构造一个string_view , 然后拷贝构造string_view即可. 代价基本仅仅是1 data_pointer + 1 data_len. 远小于拷贝整个string的代价.
        1. string_view的substr函数的时间复杂度是O(1).(移动data_pointer构造string_view即可)
    • 注意
      • string_view范围内的字符可能不包含\0
      • 从[const] char*构造string_view对象时间复杂度O(n).(为了遍历获取data_len)
      • string_view指向的内容的生命周期可能比其本身短
    • 指导 : 约束少,使用自由,难以保证data的生命周期长于string_view. 故我们应将string_view作为函数形参,因为如果该参数仅仅在函数体内使用而不传递出去,这样使用是安全的。
      • 当然string_view作为函数形参 , 整个函数中 绝对不会出现data失效的问题.
      • 不过可以看到 cs144中依然返回了string_view(Buffer.h) ,因为Buffer内部通过shared_ptr保证了data的生命周期 ?