如何有效地为std :: string的子字符串获取`string_view`

看到

使用http://en.cppreference.com/w/cpp/string/basic_string_view作为参考,我认为没有办法更优雅地做到这一点:

std::string s = "hello world!";
std::string_view v = s;
v = v.substr(6, 5); // "world"

更糟糕的是,幼稚的方法是一个陷阱,并留下v了对临时对象的悬挂:

std::string s = "hello world!";
std::string_view v(s.substr(6, 5)); // OOPS!

似乎记得类似的东西,可能在标准库中添加了一个将子字符串作为视图返回的内容:

auto v(s.substr_view(6, 5));

我可以想到以下解决方法:

std::string_view(s).substr(6, 5);
std::string_view(s.data()+6, 5);
// or even "worse":
std::string_view(s).remove_prefix(6).remove_suffix(1);

坦白说,我认为这些都不是很好。现在,我能想到的最好的事情就是使用别名来使事情变得不再那么冗长。

using sv = std::string_view;
sv(s).substr(6, 5);
理查德·霍奇斯

有自由功能路线,但是除非您也提供过载,std::string否则这是一个蛇坑。

#include <string>
#include <string_view>

std::string_view sub_string(
  std::string_view s, 
  std::size_t p, 
  std::size_t n = std::string_view::npos)
{
  return s.substr(p, n);
}

int main()
{
  using namespace std::literals;

  auto source = "foobar"s;

  // this is fine and elegant...
  auto bar = sub_string(source, 3);

  // but uh-oh...
  bar = sub_string("foobar"s, 3);
}

恕我直言,string_view的整个设计是一个恐怖的表演,它将把我们带回到一个充满节节和生气客户的世界。

更新:

甚至添加超载std::string也是恐怖的表演。看看您是否能发现微妙的段错误定时炸弹...

#include <string>
#include <string_view>

std::string_view sub_string(std::string_view s, 
  std::size_t p, 
  std::size_t n = std::string_view::npos)
{
  return s.substr(p, n);
}

std::string sub_string(std::string&& s, 
  std::size_t p, 
  std::size_t n = std::string::npos)
{
  return s.substr(p, n);
}

std::string sub_string(std::string const& s, 
  std::size_t p, 
  std::size_t n = std::string::npos)
{
  return s.substr(p, n);
}

int main()
{
  using namespace std::literals;

  auto source = "foobar"s;
  auto bar = sub_string(std::string_view(source), 3);

  // but uh-oh...
  bar = sub_string("foobar"s, 3);
}

编译器在这里没有发现任何警告。我敢肯定,代码审查也不会。

我已经说过了,再说一遍,以防c ++委员会上的任何人在看,允许从std::string到的隐式转换std::string_view是一个可怕的错误,只会使c ++蒙羞

更新资料

在cpporg留言板上提出了这个(对我来说)相当令人震惊的string_view属性后,我的顾虑便变得冷漠。

该小组的建议的共识是,std::string_view绝不能从函数中返回它,这意味着我在上面的第一个提议是错误的形式。

当然,如果偶然发生(例如通过模板扩展),则没有编译器帮助来捕获时间。

因此,std::string_view应格外小心,因为从内存管理的角度来看,它等效于指向另一个对象状态的可复制指针,该对象可能不再存在。但是,它在所有其他方面的外观和行为都类似于值类型。

因此,代码如下:

auto s = get_something().get_suffix();

get_suffix()返回std::string(按值或引用)时是安全的

但是如果将get_suffix()重构为返回a,则为UB std::string_view

在我的拙劣观点中,这意味着auto如果将其调用的库重构为std::string_view代替的返回值使用返回的字符串存储的任何用户代码都将中断std::string const&

因此,从现在开始,至少对于我来说,“几乎总是自动的”必须变成“几乎总是自动的,除非是字符串”。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用字符串有效地管理内存?

来自分类Dev

bash脚本:如何有效地在字符串末尾附加字符(O(1))

来自分类Dev

如何有效地提取C ++中的字符串模式?

来自分类Dev

如何有效地找到字符数相等的最长子字符串

来自分类Dev

如何在vim中有效地添加括号或字符串?

来自分类Dev

如何有效地找到两个给定的子字符串之间的字符串?

来自分类Dev

有效地替换字符串中的子字符串

来自分类Dev

如何通过有效地连接字符来构造字符串?

来自分类Dev

如何在linq中有效地加入字符串?

来自分类Dev

如何向后读取文件以有效地找到子字符串

来自分类Dev

有效地分割格式为“ {{},{},...}”的字符串

来自分类Dev

如何有效地排序R中字符串中的字符?

来自分类Dev

我们如何有效地检查Python中字符串是否为十六进制

来自分类Dev

如何从数组源缩写后有效地添加字符串?

来自分类Dev

如何有效地匹配两个数据帧中的字符串

来自分类Dev

如何在R中有效地对字符串中的字母重新排序?

来自分类Dev

如何用另一个std :: string的迭代值有效地替换std :: string中的字符?

来自分类Dev

如何基于行的字符串值有效地获取数据

来自分类Dev

如何从点有效地创建线串?

来自分类Dev

PHP:如何(有效地)替换这些字符串?

来自分类Dev

如何有效地提取C ++中的字符串模式?

来自分类Dev

如何有效地找到字符数相等的最长子字符串

来自分类Dev

如何有效地找到两个给定的子字符串之间的字符串?

来自分类Dev

如何在javascript中有效地匹配字符串中间的数字?

来自分类Dev

如何在linq中有效地加入字符串?

来自分类Dev

如何有效地从大txt文件中仅读取字符串

来自分类Dev

如何有效地建立这个字符串?

来自分类Dev

有效地将多维数组中元素的引用编码为字符串

来自分类Dev

如何有效地从 Scala 中的字符串中删除非单词字符?

Related 相关文章

  1. 1

    如何使用字符串有效地管理内存?

  2. 2

    bash脚本:如何有效地在字符串末尾附加字符(O(1))

  3. 3

    如何有效地提取C ++中的字符串模式?

  4. 4

    如何有效地找到字符数相等的最长子字符串

  5. 5

    如何在vim中有效地添加括号或字符串?

  6. 6

    如何有效地找到两个给定的子字符串之间的字符串?

  7. 7

    有效地替换字符串中的子字符串

  8. 8

    如何通过有效地连接字符来构造字符串?

  9. 9

    如何在linq中有效地加入字符串?

  10. 10

    如何向后读取文件以有效地找到子字符串

  11. 11

    有效地分割格式为“ {{},{},...}”的字符串

  12. 12

    如何有效地排序R中字符串中的字符?

  13. 13

    我们如何有效地检查Python中字符串是否为十六进制

  14. 14

    如何从数组源缩写后有效地添加字符串?

  15. 15

    如何有效地匹配两个数据帧中的字符串

  16. 16

    如何在R中有效地对字符串中的字母重新排序?

  17. 17

    如何用另一个std :: string的迭代值有效地替换std :: string中的字符?

  18. 18

    如何基于行的字符串值有效地获取数据

  19. 19

    如何从点有效地创建线串?

  20. 20

    PHP:如何(有效地)替换这些字符串?

  21. 21

    如何有效地提取C ++中的字符串模式?

  22. 22

    如何有效地找到字符数相等的最长子字符串

  23. 23

    如何有效地找到两个给定的子字符串之间的字符串?

  24. 24

    如何在javascript中有效地匹配字符串中间的数字?

  25. 25

    如何在linq中有效地加入字符串?

  26. 26

    如何有效地从大txt文件中仅读取字符串

  27. 27

    如何有效地建立这个字符串?

  28. 28

    有效地将多维数组中元素的引用编码为字符串

  29. 29

    如何有效地从 Scala 中的字符串中删除非单词字符?

热门标签

归档