问题标签 [std-span]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 什么是“跨度”,我应该什么时候使用?
最近我收到了span<T>
在我的代码中使用 's 的建议,或者在使用 's 的网站上看到了一些答案span
- 据说是某种容器。但是 - 我在 C++17 标准库中找不到类似的东西。
那么这是什么神秘span<T>
的,如果它是非标准的,为什么(或何时)使用它是一个好主意?
c++ - 将非拥有位容器基于 std::vector 是个好主意吗? 标准::跨度?
在我的几个项目中,我越来越需要处理内存中的连续位序列 - 高效(*)。到目前为止,我已经编写了一堆可内联的独立函数,以选择“位容器”类型(例如uint32_t
)为模板,用于获取和设置位,将“或”和“与”应用于它们的值,定位容器,以位为单位的长度转换为以字节为单位的大小或容器中的长度等......看起来这是编写类的时间。
我知道 C++ 标准库有一个专门化的std::vector<bool>
,这被许多人认为是一个设计缺陷——因为它的迭代器不暴露实际bool
的 s,而是代理对象。无论这对于专业化来说是一个好主意还是一个坏主意,这绝对是我正在考虑的东西 - 一个显式的位代理类,希望它“总是”被优化掉(用constexpr
,noexcept
和很好地润滑inline
)。因此,我正在考虑可能std::vector
从标准库实现之一改编代码。
另一方面,我的预期课程:
- 永远不会拥有数据/位-它将接收起始位容器地址(假设对齐)和位长度,并且不会分配或释放。
- 它将无法动态或以其他方式调整数据大小 - 即使在保留与 std::vector::resize() 相同的空间量时也不行;它的长度将在其生命周期/范围内固定。
- 它不应该对堆一无所知(并且在没有堆时工作)
从这个意义上说,它更像是位的跨度类。那么也许从跨度开始呢?我不知道,跨度仍然不标准;并且跨度中没有代理...
那么什么是我实现的良好基础(编辑:不是基类)?std::vector<bool>
? std::span
? 两个都?没有任何?或者 - 也许我正在重新发明轮子,这已经是一个已解决的问题?
笔记:
- 位序列长度在运行时是已知的,而不是编译时;否则,正如@SomeProgrammerDude 建议的那样,我可以使用
std::bitset
. - 我的班级不需要“成为”跨度或“成为”向量,所以我没有考虑专门研究其中任何一个。
(*) - 到目前为止,SIMD 效率不高,但可能会在以后出现。此外,这可以在我们不 SIMDize 而是假装通道是正确线程的 CUDA 代码中使用。
c++ - 引用 std::whatever 或 not_yet_in_std::whatever 的惯用方式是什么?
我喜欢跨度,所以我gsl::span
在这里和那里使用。但是 - 在 C++20 中,它将std::span
改为*。我使用std::optional
,但对于 C++14 代码,它需要是std::experimental::optional
. 等等。
在这些变体(有时可能超过两个)之间进行编译时选择的惯用且面向未来的方法是什么,以便我的实际代码可以只使用一个标记序列,该标记序列编译为正确选择跨度,或可选,或其他类似的构造?
注意:我想避免污染全局命名空间。
* 好吧,从技术上讲,我也可以gsl::span
稍后使用,但这个问题的想法是在标准可用时使用标准中的内容,并在此之前使用最接近的替代方案。
c++ - 使 Eclipse CDT 正确忽略我的 GSL 跨度标头
我使用指南支持库gsl::span
(来自 Neil Macintosh 的实现) - 标题位于/usr/local/src/gsl/include
.
我也使用 nVIDIA nSight 9.2,即 Eclipse CDT 版本 8.4.0.nvidia-something。我已将包含文件夹添加为项目设置下的 CDT 用户条目 | 构建 | C/C++ 通用 | 预处理器包括路径、宏等 - 但这不会影响索引器,它会忽略文件。此外,语法highligher 不喜欢它,因为它没有.hpp
/ .h
/.hxx
前缀。
如何才能span
正确识别标题?
c++ - 我应该如何表示我拥有的连续元素序列?
我在连续的内存中有一堆类型的数据,我得到了T *
; 而且我也知道元素的数量(std::size_t
虽然它并不重要)。
我想使用一些单一类型或数据结构来表示我的类型数据。
现在,我所拥有的是用于构建的信息......
- A
gsl::span<T>
,但有所有权。 - A
gsl::owner<T *>
,但有大小。
我将使用什么类型/结构/容器来表示有关此数据的所有信息?
笔记:
- 显然我可以使用 GSL 构造;C++2a 或 Boost 中的东西也很好。
owner
我在想一个和span
——也许是的嵌合体gsl::owner<gsl::span<T>>
;但我不太喜欢这个主意。
c++ - 为什么 std::span 缺少 size_type?
我一直在将使用我的自制 span 类的旧代码更新为更符合 C++20 的代码std::span
,并且我收到编译错误,因为std::span
没有size_type
,而是有index_type
. index_type
关于是否应该签约一直存在巨大的争议,但为什么要跳过size_type
呢?这破坏了期望容器(或类似容器的对象)具有size_type
.
c++ - 如何编写 C++ 库以使用 span 的任何实现?
我正在编写一个 I/O 库,用户需要在其中提供要读取或写入的内存块。让我的图书馆接受 aspan<T>
似乎是最自然的选择,因为:
- 它不会将容器选择强加给用户。他们可以使用原始指针,
std::vector
或任何其他具有连续存储的容器。 - 它允许我确保内存访问是安全的,因为我知道缓冲区的大小。
不幸的是,span<T>
在 Boost、GSL 和标准库(从 C++20 开始)中存在相互竞争的实现。这些实现的接口是兼容的,从用户的角度来看,他们使用哪一个并不重要。
如何编码我的 I/O 函数,以便它们与 ? 的任何各种实现一起工作span
?
目前我能想到的唯一方法是包含我自己的实现,span
它可以从任何带有::element_type
,.data()
和.size()
.
重要的是仍然支持来自容器的隐式转换,以便用户可以简单地传递一个std::vector
. 例如:
c++ - 为什么 std::span 是指针+大小而不是两个迭代器
似乎std::span
在 C++20 中的定义类似于
并不是
哪个更通用(适用于 std::list、std::map 等)?
c++ - std::cspan 发生了什么?
std::span
已被选入 C++20。我假设除了std::span
,还会有一个这样定义的便利别名:
对我来说,这似乎是一个非常方便的别名。我可能会cspan
更频繁地使用span
!根据cppreference,cspan
不存在。cspan
在这篇论文中提到了一个似乎暗示它在某个时候在标准中。我找不到任何其他提及。
那么发生了cspan
什么?它被删除了吗?它曾经存在过吗?
c++ - span 是否传播 const?
标准容器传播 const。也就是说,如果容器本身是 const,则它们的元素自动为 const。例如:
内置数组也传播 const:
但是,我注意到std::span
(大概)不会传播 const。最小可重现示例:
为什么这段代码可以正常工作?为什么std::span
对待 const 不同于标准容器?