中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用C++17 的 std::string_view避免字符串拷貝

發布時間:2020-10-26 14:19:26 來源:億速云 閱讀:706 作者:Leah 欄目:開發技術

如何使用C++17 的 std::string_view避免字符串拷貝?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

C++中std::string是日常Coding中經常使用的一個類,使用起來非常方便,但是也存在一些弊端。

如下代碼,參數傳遞的過程發生了內存分配(Memory Allocation)和內存拷貝。

void fun(const std::string& s) {
  std::cout << s << std::endl;
}

const char* ch = "hello world";

// bad way, expensive if the string is long
fun(ch); 

再看下面的常用的字符串截取實現:

// very long string
std::string str = "lllloooonnnngggg sssstttrrriiinnnggg"; 

// bad way, expensive if the string is long
std::cout << str.substr(15, 10) << '\n';

為了進一步的壓榨程序的性能,需要移除掉這些昂貴的字符串內存分配和拷貝操作。C++17中提供了std::string_view可以幫助我們實現這一功能,該類并不持有字符串的拷貝,而是與源字符串共享其內存空間。

string_view構造函數

constexpr basic_string_view() noexcept; (since C++17)
constexpr basic_string_view(const basic_string_view& other) noexcept = default; (since C++17)
constexpr basic_string_view(const CharT* s, size_type count);(since C++17)
constexpr basic_string_view(const CharT* s); (since C++17)
template<class It, class End>

雖然沒有定義參數為std::string的std::string_view函數,下面的代碼仍然可以通過編譯。

std::string str("hello string view!");
std::string_view sview(str);

因為std::string類重載了std::string到std::string_view的轉換操作符。

operator basic_string_view<charT, traits>() const noexcept;

std::string_view避免內存拷貝

有了string_view,我們就可以很好的解決文章開頭提到的問題。

void fun(const std::string_view& s) {
  std::cout << s << std::endl;
}

const char* ch = "hello world, char";
fun(ch); 

const std::string str = "hello world, string";
fun(str);

fun({ch, 5});

有了std::string_view,函數參數不管是字符串數組指針,還是std::string,都不需要拷貝內存源字符串。

// very long string
std::string str = "lllloooonnnngggg sssstttrrriiinnnggg";

//Good way - No copies are created!
std::string_view view = str;

// string_view::substr returns a new string_view
std::cout << view.substr(15, 10) << '\n';

同理,字符串的substr()函數也不需要再進行拷貝了,這對于非常長的字符串,可以有效的提升程序的性能表現。

std::string_view注意事項

由于std::string_view并不持有字符串的內存,所以它的生命周期一定要比源字符串的生命周期長。一些典型的生命周期管理錯誤的例子:

std::string_view sv = std::string("hello world");

std::string_view fun() {
 std::string str("hello world");
 return std::string_view(str);
}

std::string_view的結尾并沒有\0結束符,所以在輸出std::string_view的時候要注意邊界,如下代碼:

#include <iostream>
#include <vector>
#include <string>
#include <string_view>

int main() {
  const char* ch = "hello world";
  
  std::string_view sv(ch, 2);
  
  std::cout << sv << std::endl;
  
  std::cout << sv.data() << std::endl;
  
  return 0;
}

程序輸出:

he
hello world

std::cout << sv.data() << std::endl; 這行代碼輸出了hello world,這是因為sv仍然指向源字符串內存,調用sv.data()打印時,仍然沿用了C++對于字符串的約定,直到遇到結束符\0時,打印才結束,這時候就輸出了完整的源字符串內容。當然這里明顯是不符合預期的,尤其是std::string_view指向的字符串沒有\0結束符的時候,程序很容易出現潛在的內存問題。所以此處一定要小心。

看完上述內容,你們掌握如何使用C++17 的 std::string_view避免字符串拷貝的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

应城市| 子洲县| 大宁县| 巩义市| 衡山县| 桂阳县| 比如县| 金塔县| 雅安市| 从江县| 兴宁市| 平和县| 喀喇沁旗| 黔东| 开江县| 淮南市| 旬阳县| 衡东县| 邢台县| 芦山县| 克东县| 稻城县| 文成县| 鲁甸县| 抚顺县| 德江县| 乡宁县| 炎陵县| 那曲县| 巴彦淖尔市| 辽阳市| 阿坝县| 高台县| 沁源县| 丰城市| 汉源县| 静宁县| 罗城| 洪洞县| 长兴县| 仙桃市|