首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >什么是“span”,什么时候应该使用一个?

什么是“span”,什么时候应该使用一个?
EN

Stack Overflow用户
提问于 2018-04-17 05:31:01
回答 1查看 0关注 0票数 0

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

那么,这是什么神秘的span<T>,为什么(或什么时候)使用它是一个好主意,如果它不是标准的?

EN

回答 1

Stack Overflow用户

发布于 2018-04-17 15:19:28

它是什么?

A span<T>是:

  • 内存中某处T型值的连续序列的一个非常轻量级的抽象。
  • 基本上有struct { T * const ptr; size_t length; }一堆便利方法。
  • 非拥有类型(即“引用类型”而不是“值类型”):它从不分配或解除分配任何东西,也不会使智能指针保持活动状态。

它以前被称为一个array_view,甚至更早array_ref

我应该什么时候使用它?

首先,何时使用它:

  • 不要在代码中使用它,可能只是采取任何一对开始和结束迭代器一样的std::sortstd::find_ifstd::copy和所有的超级通用模板功能。
  • 如果你有一个标准的库容器(或者一个Boost容器等),那么不要使用它,你知道它适合你的代码。它无意取代它们中的任何一个。

现在什么时候才能真正使用它:

span<T>分别使用(分别span<const T>),而不是一个独立的T*(分别const T*),你有长度值。所以,替换功能如下: void read_into(int* buffer, int buffer_size); 有: void read_into(span<int> buffer);

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

哦,跨度真棒!使用span...

  • 意味着您可以像使用精简的标准库容器一样使用该指针+长度/开始+结束指针组合,例如:
    • for (auto& x : my_span) { /* do stuff */ }
    • std::find_if(my_span.begin(), my_span.end(), some_predicate);

    ......但是绝大多数的容器类别都没有发生。

  • 有时让编译器为你做更多的工作。例如,这个: 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 ++核心指南中找到它- 但你可以发现漂移。

为什么它不在标准库(从C ++ 17开始)?

  1. 它目前的形式仍然很新,与C ++核心指南项目一起构想,该项目自2015年以来才刚刚起步。(尽管正如评论者指出的那样,它有更早的历史。)
  2. 它可能很快成为标准库的一部分(C ++ 20)。请参阅2017年6月Neil Macintosh 的提案。

那么如果它不在标准库中,我该如何使用它呢?

它是核心指南的支持库(GSL)的一部分。实现:

  • Microsoft / Neil Macintosh的GSL包含一个独立的实现:gsl/span
  • GSL-Lite是整个GSL的单一文件实现(它并不那么大,不用担心),包括span<T>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100004423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档