什么是“跨度”以及何时应该使用“跨度”?

2023-11-24

最近我收到了使用建议span<T>在我的代码中,或者在网站上看到了一些答案,其中使用span's - 据说是某种容器。但是 - 我在 C++17 标准库中找不到类似的东西。

那么这究竟是什么呢?span<T>,如果它是非标准的,为什么(或何时)最好使用它?


它是什么?

A span<T> is:

  • 类型的连续值序列的非常轻量级的抽象T记忆中的某个地方。
  • 基本上是一个struct { T * ptr; std::size_t length; }有很多方便的方法。
  • 非拥有类型(即“参考类型”而不是“值类型”):它从不分配或释放任何东西,也不保持智能指针处于活动状态。

它以前被称为array_view甚至更早array_ref.

我应该什么时候使用它?

首先,当not使用跨度:

  • 不要在代码中使用只能接受任何一对开始和结束迭代器的跨度(例如std::sort, std::find_if, std::copy和其他模板化函数<algorithm>),并且也不在采用任意范围的代码中(请参阅C++20 范围信息库关于那些)。跨度比一对迭代器或范围具有更严格的要求:元素连续性以及元素在内存中的存在。
  • 如果您有一个标准库容器(或 Boost 容器等),并且您知道它最适合您的代码,请不要使用跨度。 spans 并不是为了取代现有的容器。

现在讨论何时实际使用跨度:

Use span<T>(分别,span<const T>)而不是独立的T*(分别const T*)当分配的长度或大小也很重要时。因此,替换如下函数:

void read_into(int* buffer, size_t buffer_size);

with:

void read_into(span<int> buffer);

我为什么要使用它?为什么这是一件好事?

哦,跨度太棒了!使用跨度...

  • 意味着您可以像使用精美的标准库容器一样使用指针+长度/开始+结束指针组合,例如:

    • for (auto& x : my_span) { /* do stuff */ }
    • std::find_if(my_span.cbegin(), my_span.cend(), some_predicate);
    • std::ranges::find_if(my_span, some_predicate);(在 C++20 中)

    ...但大多数容器类绝对不会产生任何开销。

  • 有时让编译器为您做更多的工作。例如,这个:

    int buffer[BUFFER_SIZE];
    read_into(buffer, BUFFER_SIZE);
    

    变成这样:

    int buffer[BUFFER_SIZE];
    read_into(buffer);
    

    ...这将做你想做的事。也可以看看指南 P.5.

  • 是通过的合理替代方案const vector<T>&当您希望数据在内存中连续时起作用。再也不用被 C++ 大师骂了!

  • 有助于静态分析,因此编译器也许能够帮助您捕获愚蠢的错误。

  • 允许调试编译工具进行运行时边界检查(即span的方法中会有一些边界检查代码#ifndef NDEBUG ... #endif)

  • 表示您的代码(使用跨度)不拥有指向的内存。

使用起来更有动力spans,您可以在C++ 核心指南- 但你明白了。

但它在标准库中吗?

edit: Yes, std::span已通过该语言的 C++20 版本添加到 C++ 中!

为什么只在 C++20 中?嗯,虽然这个想法并不新鲜,但它目前的形式是与C++ 核心指南项目是2015年才开始成型的,所以花了一段时间。

那么,如果我编写的是 C++17 或更早版本,该如何使用它呢?

它是的一部分核心准则的支持库 (GSL)。实施:

  • 微软/尼尔·麦金塔GSL包含一个独立的实现:gsl/span
  • GSL-Lite是整个 GSL 的单头实现(它没有那么大,不用担心),包括span<T>.

GSL 实现通常假设一个实现 C++14 支持的平台 [12]。这些替代的单标头实现不依赖于 GSL 设施:

  • martinmoene/span-lite需要 C++98 或更高版本
  • tcbrindle/span需要 C++11 或更高版本

请注意,这些不同的跨度实现在它们附带的方法/支持功能方面存在一些差异;它们也可能与 C++20 标准库中采用的版本有所不同。


进一步阅读:您可以在 C++17 之前的最终官方提案 P0122R7 中找到所有细节和设计注意事项:span:对象序列的边界安全视图作者:Neal Macintosh 和 Stephan J. Lavavej。虽然有点长。此外,在 C++20 中,跨度比较语义发生了变化(以下这篇短文托尼·范·埃尔德)。

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

什么是“跨度”以及何时应该使用“跨度”? 的相关文章

随机推荐

  • 如何使用 Swift 4 在 UICollection 视图中进行多项选择

    我是 swift 的新手 从头开始构建 iOS 应用程序 使用 swift 4 想要执行如下操作 1 在UICollectionView中实现多单元格选择 2 将选定的单元格数据传递到服务器 请任何人都可以帮助我 该怎么做 告诉我执行此操作
  • 如何在 Windows 上获取硬件 MAC 地址

    我正在尝试从 NIC 检索 MAC 地址 有多种方法可以获取它 本文介绍了最常见的方法 http www codeguru com Cpp I N network networkinformation article php c5451 我
  • 单击传单标记即可转到 URL

    在 R 的传单包中 有没有办法单击标记并定向到 URL 这是JS解决方案 在 R 中 添加带有 URL 的弹出窗口 library leaflet content lt paste sep br b a href http www samu
  • 如何在 mac os x yosemite (10.10) 上安装 mcrypt 扩展

    我已将 Mac OS X 更新到 Yosemite 但这样做会覆盖我的所有开发环境 所以现在 要在本地 apache 上运行 Laravel 4 我需要安装 Mcrypt 扩展 但我尝试的一切都失败了 即使是在 OS X Mavericks
  • Android 蓝牙 VS 低功耗蓝牙

    我正在尝试创建一个应用程序 只要智能手机正在运行 就需要交换少量数据 只是为了通知设备足够接近 据我了解 传统的蓝牙会消耗大量电池 因此打开几个小时是不可行的 我正在考虑 BLE 但仍然担心电池容量 Q0 是否可以在手机运行时就开启BLE
  • JQuery DatePicker 背景颜色

    我正在使用 JQuery DatePicker 的示例链接文本 在我的 asp net 页面上 但是 日期选择器的背景颜色是白色 我不知道如何改变这个 更改为默认颜色 我的asp net页面背景页面是白色的 可能是这个原因 任何帮助将不胜感
  • 如何在模板中迭代 Django CHOICES - 不使用表单或模型实例

    我目前使用选项来定义月份列表和星期几列表 我想在我的模板中显示这些选择列表 而不必与特定实例或表单相关 例如 在我的模型中 MONTH CHOICES 01 January 02 February 03 March etc DAY CHOI
  • file_get_contents() 与使用 http/1.1 的上下文显着降低下载速度

    使用每个图像下载下面的代码 file get contents 平均需要 8 15 秒 如果我不在 file get contents 上使用上下文 则图像下载时间不到一秒 如果我将 opts 更改为 下面 我将获得与 file get c
  • 如何 - 单个 MongoDB 上的多个 Meteor 应用程序 - 相同的集合?

    以前有人问过这样的问题 如何在 Meteor 应用程序之间共享 MongoDB 集合 然而 答案并不清楚 我需要将 Meteor 公共应用程序和管理应用程序分开 出于多种原因 但主要是安全性和代码管理 使用接受的答案 export MONG
  • 有没有办法将进程的当前WorkingSet扩展到1GB? [复制]

    这个问题在这里已经有答案了 可能的重复 在C 中 有没有办法强制进程的WorkingSet为1GB 我们希望提前将 NET 进程的工作集增加到 1GB 以避免页面错误 有没有办法在 NET 中做到这一点 Update 不幸的是 即使我们打电
  • 如何删除babel添加的全局“use strict”

    我正在使用 use strict 的函数形式 并且不想要 Babel 在转译后添加的全局形式 问题是我正在使用一些不使用 use strict 模式的库 并且在连接脚本后可能会抛出错误 正如 Babel 6 中已经提到的 它是transfo
  • 如何在 Kubernetes 中设置自定义 HTTP 错误

    我想创建一个自定义 403 错误页面 目前我已经创建了一个 Ingress 并且在注释中我有这样的内容 nginx ingress kubernetes io whitelist source range 100 01 128 0 20 8
  • 带有缺失值的 dplyr 交叉表

    我想在 R 中使用dplyr 我有充分的理由不只使用底座table 命令 table mtcars cyl mtcars gear 3 4 5 4 1 8 2 6 2 4 1 8 12 0 2 library dplyr library t
  • 禁用其他网站的 iframe 嵌入

    我想禁用从我的网站到其他网站的 iframe 嵌入页面 我做了这个js 脚本有效 但我有 page01 php 和 page02 php 我想在 page01 php 源代码中插入 page02 php 的 iframe 当我这样做时 我被
  • 使用嵌套自定义对象进行 NSCoding?

    我有一系列嵌套对象 我需要将它们通过 NSCoding 协议 以便我可以将顶级对象保存到 NSUserDefaults 中 这是对象的结构 导师 班 NSMutableArray 保存 的实例 类 类 NSMutableArray 保存 的
  • 覆盖溢出:用 z-index 隐藏

    我正在使用 coda bubble jquery 插件 我需要让我的气泡在溢出隐藏 div 中弹出 这是我的示例代码
  • jQuery jqGrid 当编辑行完成时显示消息

    我在这里关注本教程http www trirand com blog jqgrid jqgrid html在 实时数据操作 gt 编辑行 我的网格从脚本接收数据a php 之后用户可以通过jqGrid修改这个数据 jqGrid修改数据后会将
  • 如果从函数返回,局部变量的成员子对象也会被移动吗?

    C 11 标准规定 如果满足复制省略的条件 12 8 31 实施应处理returned 局部左值变量和函数参数 首先作为右值 移动 如果重载解析未按详细说明成功 则应将其视为左值 复制 12 8 class copy p32 当满足或将满足
  • 在 R 中将列表转换为数据帧

    所以我有一个清单 说 L1 lt list 1 10 5 14 10 19 现在我试图将列表的输出作为数据帧 以便我的输出看起来 1 1 2 3 4 5 6 7 8 9 10 2 5 6 7 8 9 10 11 12 13 14 3 10
  • 什么是“跨度”以及何时应该使用“跨度”?

    最近我收到了使用建议span