比较 std::string_view 和子字符串 string_view

Posted

技术标签:

【中文标题】比较 std::string_view 和子字符串 string_view【英文标题】:Comparing a std::string_view and a substring string_view 【发布时间】:2018-09-23 20:15:59 【问题描述】:

假设我们有一个 string_view 和另一个 string_view,它是第一个 string_view 的子集:

using namespace std; // just to shorten the example...

string_view s"abc def";
auto t = s.substr(4);
auto u = s.substr(0, 4);

cout << *(s.begin() + 4) << "  " << *t.begin() << '\n';
cout << ((s.begin() + 4) == t.begin());
cout << (s.end() == t.end());
cout << ((s.begin() +5) == t.begin());
cout << ((s.begin() +5) == (t.begin() + 1));
cout << ((s.begin() + 4) == u.end()); // true

所有比较都适用于 gcc (9 HEAD) 和 clang (8 HEAD) 下的 Linux。在 Windows Visual c++ (15.7.6) 下,不允许比较两个迭代器(在调试模式下,您会收到断言错误 cannot compare incompatible string_view iterators for equality)。

接下来是指针比较:

string_view s"abc def";
char const*& it...; // contains pointer to some location in s
auto t = s.substr(4);

it == s.end(); // works in gcc/clang - fails to compile in Visual studio

因此,当您尝试在 Visual C++ 中修复它时,您想要比较地址 it == &amp;*s.end() 但这会失败,因为 end() 迭代器不应该被取消引用(如果我没记错的话是 UB)所以你会得到 cannot dereference end string_view iterator

boost::string_view 支持 it == s.end() 比较,所以我很惊讶 std 实现受到更多限制(因此对跨平台工作的用户友好性要低得多)

我知道两个不同容器的迭代器比较是 UB,但 string_view 不是容器(它不拥有底层内存)它是某种形式的智能指针,所以我希望语言允许我比较这样的迭代器信任我认为视图指向同一容器的不同(或相同)子集。

所以我的问题是我怎样才能使这样的事情只与 string_view 一起工作?

(意思是不需要创建一个包含两个迭代器的自定义范围类,因为这会破坏首先使用 std::string_view 的目的)

【问题讨论】:

您的用例是什么?我认为没有理由用 string_views 做你想做的事? @NoSenseEtAl 我正在修改 boost::beast 以将其与 std::string_view 一起使用,而不是 boost::string_view 尽可能少的更改(参见 basic_parsed_list const_iterator 类:github.com/boostorg/beast/blob/develop/include/boost/beast/http/…)。在 Linux 上这就是全部:github.com/boostorg/beast/pull/1241 而在 Windows 上则需要更多的工作...... @Justin 这是it == s.end() 部分,将其更改为it == &amp;*s.end() 会触发运行时断言错误,即不应取消引用结束迭代器(对于 begin 和 end-1 之间的其余指针,工作)。 【参考方案1】:

您似乎想要使用原始指针。

如果您想使用原始指针,请使用 .data() 而不是 .begin().data()+.size() 而不是 end()

这些指针的行为就像您希望字符串视图迭代器的行为一样。

如果您需要返回迭代器,ptr-.data()+.begin() 会重建一个迭代器(并且it-begin()+.data() 会往返返回 ptr)。

【讨论】:

以上是关于比较 std::string_view 和子字符串 string_view的主要内容,如果未能解决你的问题,请参考以下文章

c++17比较string_view和string时的歧义

使用 std::string_view 的子字符串控制台输出 [关闭]

为啥 std::string_view 比 const char* 快?

删除 std::string_view 的最后一个字符

将 std::string_view 与 api 一起使用,期望以 null 终止的字符串

将 std::string_view 与 api 一起使用,期望以 null 终止的字符串