簡體   English   中英

為什么我不能從 std::string 迭代器創建 std::string_view ?

[英]Why can't I create a std::string_view from std::string iterators?

可以輕松地從std::string創建std::string_view 但是,如果我想使用 std::string 的迭代器創建一系列std::string std::string字符串視圖是行不通的。

這是我嘗試過的代碼: https ://gcc.godbolt.org/z/xrodd8PMq

#include <iostream>
#include <string>
#include <string_view>
#include <iterator>

int main()
{
    std::string str{"My String"};
    std::string_view strView{str};  // works
    //std::string_view strSubView{str.begin(), str.begin() + 2}; // error
}

當然,也許我們可以從str中取出子字符串並用於創建字符串視圖strSubView ,但是還有一個額外的字符串創建。

我發現std::basic_string_view的第五個構造函數采用了迭代器的范圍。

template<class It, class End>
constexpr basic_string_view(It first, End last);

但它只是std::string的迭代器還是std::basic_string_view本身? 如果不是std::string的迭代,為什么我們不應該有一個,畢竟字符串視圖:

描述了一個對象,該對象可以引用類似字符的對象的連續連續序列!

取char的連續序列的范圍,不應該算嗎?

該構造函數是在 C++20 中添加的 如果您使用 C++17 編譯器進行編譯,則它不存在。

你可以寫一個做同樣事情的函數

std::string_view range_to_view(std::string::iterator first, std::string::iterator last) {
    return first != last ? { first.operator->(), last - first } : { nullptr, 0 };
}

為什么我不能從 std::string 迭代器創建 std::string_view?

您可以,但僅從 C++20 開始。

但它只是 std::string 的迭代器還是 std::basic_string_view 本身?

它是適當值類型的任何連續迭代器。 字符串和字符串視圖迭代器都被接受。 文檔中列出了確切的約束。

這意味着在 C++17 中沒有辦法做到這一點?

沒有辦法使用不存在的構造函數,但是有幾種方法可以獲取所需的字符串視圖。 這是一個:

std::string_view strSubView = strView.substr(0, 2);

或沒有中間變量:

std::string_view strSubView = std::string_view{str}.substr(0, 2);

或者如果您只有這些迭代器並且無法訪問字符串:

std::string_view strSubView {&*first, last - first};

至於取消引用迭代器是不安全的(即在指向 end 的迭代器上調用operator*operator->可能會使您的應用程序崩潰),我看到的 C++17 中唯一的方法是調用string_view::substr()並且僅使用迭代器來計算大小和索引。

constexpr std::string_view make_string_view(std::string_view str, 
                                            std::string_view::iterator first, 
                                            std::string_view::iterator last) noexcept
{
    return str.substr(first - str.begin(), last - first);
}

對於std:string使用std::string::data()作為初始指針。

std::string_view make_string_view(std::string const& str, 
                                  std::string::const_iterator first, 
                                  std::string::const_iterator last) noexcept
{
    return std::string_view(str.data() + (first - str.begin()), last - first);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM