为什么我不能从 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
范围内的字符串视图是行不通的。
这是我试过的代码: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
的迭代,为什么我们不应该有一个,毕竟字符串视图:
describes an object that can refer to a constant contiguous sequence
of char-like objects !
取char连续序列的范围,是不是应该算一下?
That constructor is added in 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 };
}
Why can not I create a std::string_view from std::string itertors?
你可以,但只能从 C++20 开始。
But is it only the iterators of the std::string or just std::basic_string_view 's itself?
它是适当值类型的任何连续迭代器。接受字符串和字符串视图迭代器。文档中列出了确切的约束条件。
That means in C++17 there is no way to do it??
无法使用不存在的构造函数,但有多种方法可以获取所需的字符串视图。这是一个:
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);
}
可以轻松地从 std::string
创建 std::string_view
。但是,如果我想使用 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
的迭代,为什么我们不应该有一个,毕竟字符串视图:
describes an object that can refer to a constant contiguous sequence of char-like objects !
取char连续序列的范围,是不是应该算一下?
That constructor is added in 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 };
}
Why can not I create a std::string_view from std::string itertors?
你可以,但只能从 C++20 开始。
But is it only the iterators of the std::string or just std::basic_string_view 's itself?
它是适当值类型的任何连续迭代器。接受字符串和字符串视图迭代器。文档中列出了确切的约束条件。
That means in C++17 there is no way to do it??
无法使用不存在的构造函数,但有多种方法可以获取所需的字符串视图。这是一个:
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);
}