在 C++11 中,返回指向 std::string 中某个位置的引用/指针的最高效方法是什么?

2024-05-11

我正在构建一个使用的文本解析器std::string作为字符串的核心存储。

我知道这不是最佳的,编译器内的解析器为此使用优化的方法。在我的项目中,我不介意损失一些性能来换取更清晰和更容易的维护。

一开始,我将大量文本读入内存,然后扫描每个字符以构建一组有序的标记,这是一个简单的词法分析器。目前我正在使用std::string来表示令牌的文本,但我想通过使用原始文本的引用/指针来改进这一点。

根据我的阅读,返回并保留迭代器是一种不好的做法,并且引用迭代器也是一种不好的做法std::string内部缓冲区。

关于如何以“干净”的方式实现这一点有什么建议吗?


有建议可以补充string_view即将发布的标准中的 C++。

A string_view是字符上的非拥有可迭代范围,具有您期望的字符串类的许多实用程序和属性,但您不能插入/删除字符(并且在某些子类型中编辑字符通常被阻止)。

我建议尝试这种方法——编写您自己的方法(在您自己的实用程序命名空间中)。 (无论如何,您应该拥有自己的实用程序命名空间,用于可重用的代码片段)。

核心数据是一对char* pr std::string::iterators (or const版本)。如果用户需要一个空终止的缓冲区,to_string方法分配一个。我将从不可变(const) 字符数据。不要忘记begin and end:这使得你的视图可以迭代for(:) loops.

这个设计有一个危险,那就是原来的设计std::string必须坚持足够长的时间才能比所有观点更持久。

如果您愿意为了安全而放弃一些性能,请拥有一个视图std::shared_ptr<const std::string>它可以移动一个std::string进入,第一步将整个缓冲区移入其中,然后开始对其进行切割/解析。 (子视图创建一个指向相同数据的新共享指针)。那么你的视图类更像是一个具有共享存储的不可变字符串。

的好处shared_ptr<const>版本包括安全性、更长的视图生命周期(不再有生命周期依赖性),并且您可以轻松转发您的const“substring”类型方法std::string所以你可以编写更少的代码。

Downsides include possible incompatibility with incoming standard one1, and lower performance because you are dragging a shared_ptr around.

我怀疑随着语言即将到来和最近的改进,视图和范围在现代 C++ 中将变得越来越重要。

boost::string_ref http://www.boost.org/doc/libs/1_55_0/libs/utility/doc/html/string_ref.html显然是 C++1y 标准提案的实现。


1 however, given how simple it is to add capabilities in template metaprogramming, having a "resource owner" template argument to a view type might be a good design decision. Then you can have owning and non-owning string_views with otherwise identical semantics...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C++11 中,返回指向 std::string 中某个位置的引用/指针的最高效方法是什么? 的相关文章

随机推荐

  • SpinnerAdapter 中 getView 和 getDropDownView 的区别

    当你实现 SpinnerAdapter 时 你会得到获取下拉视图 http developer android com reference android widget SpinnerAdapter html getDropDownView
  • Ionic 3 更新后 WebpackJsonp 丢失

    我最近从 2 升级到 ionic 3 我可以为 iOS 构建应用程序 但 ionic 服务现在失败并出现以下错误 在为 iOS 构建之前 我必须手动将 main prod ts 和 main dev ts 替换为 main ts 您需要更多
  • 是否可以从数据库转储生成 knex 种子文件?

    就我而言 我使用的是 mysql 但是 我正在寻找一种通用解决方案 用于从当前运行的数据库或数据库转储生成 knex 种子文件 我可以就像是 https github com tgriesser knex issues 944 issuec
  • 如何以 JavaScript 编程方式获取旋转的 svg 文本边界

    我正在动态渲染 SVG 图像并创建旋转文本 如果旋转的文本与其他文本重叠 我需要删除该文本 但我无法测量旋转的文本来创建边界并检查下一个标签文本区域 我创建了 3 个 SVG 元素来解释 SVG 1 显示重叠的文本 SVG 2 显示重叠的旋
  • 为什么尝试使用 Hamcrest 的 hasItems 的代码无法编译?

    为什么这个不能编译 哦 怎么办 import static org junit Assert assertThat import static org junit matchers JUnitMatchers hasItems ArrayL
  • Excel如何获取一个时间间隔内的小时数?

    我有两列 Night shift start 19 00 Night end 04 00 我每天都有一些日期列 Work started 07 30 Worked ended 22 00 我想获取夜班开始和夜班结束之间的小数小时数 我需要计
  • 用Java将图像添加到数据库

    我正在尝试将图像添加到 mysql 数据库中的 BLOB 字段 图像大小将小于 100kb 但是我遇到了问题 想知道将这些数据添加到数据库的更好方法是什么 com mysql jdbc MysqlDataTruncation 数据截断 第
  • 使用 BeautifulSoup 抓取评论标签内的表格

    我正在尝试使用 BeautifulSoup 从以下网页中抓取表格 https www pro football reference com boxscores 201702050atl htm https www pro football
  • 将应用程序级别用户名/用户 ID 注入 nginx/Apache 日志

    有没有办法将应用程序级别的用户名或 id 在本例中为 django 用户名或 id 注入 Apache 或 ngnix 日志中 请注意 我不是询问 HTTP 身份验证用户名 我目前正在使用一个简短的自定义中间件将此数据添加到响应标头 如下所
  • MetadataException:无法加载指定的元数据资源

    突然间我不断收到MetadataException在实例化我生成的ObjectContext班级 App Config 中的连接字符串看起来正确 自上次工作以来没有更改 我尝试从底层数据库重新生成一个新模型 edmx 文件 没有任何更改 有
  • 比较 PHP 中的 unix 时间戳 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 在 PHP 中我有 diff abs
  • 我可以为 Android Activity 分配“默认”OnClickListener() 吗?

    我有一个 Activity 对于布局中的每个小部件 我调用 setOnClickListener 来分配我的 OnClick 处理程序 在我的 OnClick 处理程序中 我使用 switch 语句根据 View 参数的 ID 为每个按钮执
  • 在java中切换imageIcon?

    我有很多在窗口中移动的平面 线程 我想根据平面的方向切换 ImageIcon 例如 如果飞机向右飞行 则飞机的 imageIcon 是向右的 然后飞机向左飞行 则将 imageIcon 交换为飞机向左 我怎样才能在方法paintCompon
  • 媒体文件不在 cpanel 上的 django 应用程序中提供

    我有一个 django 应用程序在 cpanel 上运行 我不确定是否是我的问题 django 应用程序或 cpanel 服务器 当设置调试模式时True 我可以看到所有媒体文件 例如个人资料图片或pdf文件等 但是当设置调试模式时Fals
  • 定义自定义 Mupad 程序的一般相对搜索路径

    假设我有一个 mupad 笔记本myMupadNotebook mn在路径上 C projectFolder ABC abc 它调用程序MyMupadProcedure mu它位于 C DEF GHI 现在我有一个 Matlab 脚本mai
  • 软件音频线路输入

    这可能是也可能不是询问的地方 如果不是 就直接扔掉它 我有一个正在输出音频的软件 我想将其路由到另一个软件 简单的解决方案是将耳机插孔连接到麦克风插孔或在计算机上启用立体声混音 但是 我想要做的进一步实现将在一台机器上发生 2 个这样的实例
  • 三层 Asp.Net 应用程序中的异常处理

    1 据我了解 在three tierAsp Net应用程序我们应该通过以下方式实现异常处理 a 我们应该把try catch围绕代码块 位于三层中的任何一层 我们希望页面能够从该代码块正常恢复 当此代码生成异常时 b 我们不应该放try c
  • 在 Oracle 中创建数据库链接时出错

    我有两个数据库 需要编写跨数据库查询 所以我试图创建一个数据库链接 CREATE PUBLIC DATABASE LINK DBLink CONNECT TO SchemaName IDENTIFIED BY 123 using DBNam
  • 在 Java/Android 中检查字符串是否包含 URL 的最佳方法是什么?

    在 Java Android 中检查字符串是否包含 URL 的最佳方法是什么 最好的方法是检查字符串是否包含 com net org info 其他 或者有更好的方法吗 url 输入到 Android 中的 EditText 中 它可以是粘
  • 在 C++11 中,返回指向 std::string 中某个位置的引用/指针的最高效方法是什么?

    我正在构建一个使用的文本解析器std string作为字符串的核心存储 我知道这不是最佳的 编译器内的解析器为此使用优化的方法 在我的项目中 我不介意损失一些性能来换取更清晰和更容易的维护 一开始 我将大量文本读入内存 然后扫描每个字符以构