繁体   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