我应该用GSL跨度替换(void*,size)吗?

ein*_*ica 5 c++ guideline-support-library

假设我有

int foo(void* p, size_t size_in_bytes);
Run Code Online (Sandbox Code Playgroud)

并假设foo打字是没有意义的.我想成为一名优秀的程序员并应用C++核心指南.具体来说,我想使用跨度而不是(*,len)对.好吧,span<void>不会编译(不能添加到a void *); 和/ span<char>span<uint8_t>等等意味着foo实际上期望chars,它可能不会.

那么我应该span<something-with-size-1>在这种情况下使用,还是坚持使用void*

Nic*_*las 5

这个问题没有一般的答案.

对于一个函数来说,它需要一种span<T>方法,它需要一个连续的值数组,没有任何形式的所有权转移.如果该描述没有合理地代表正在发生的事情,那么它不应该采取span<T>.

例如:

如果函数检查缓冲区是否与我的内存空间中的某个区域相交,例如映射到文件,该怎么办?

这听起来不像是一个span<T>.听起来你应该有一个简单的聚合,其名称可以清楚地表明它意味着什么:

struct memory_region
{
  void* p;
  size_t size_in_bytes;
};
Run Code Online (Sandbox Code Playgroud)

你甚至可以给它一个成员函数来测试交叉点.如果你正在建立一个处理这些内存区域的系统,我可能会建议一个带有构造函数等的封装类类型.

该函数采用何种类型来解释数据的含义.优选地,这个含义是一般意义上的,但至少应该说明它对于所讨论的功能意味着什么.


还有一件事:

span<uint8_t>等将意味着富实际上预计字符

不,它不会.虽然uint8_t几乎肯定会有一个相同的大小unsigned char,但这并不意味着人们希望能够将一个字符数组传递给任何需要的函数span<uint8_t>.如果该函数想要宣传它接受的字符,它就会使用它unsigned char.


我的意思是说span<whatever>这意味着函数的期望值whatever.

是的,对spans 的要求是它传递T给定大小的实际s 数组.


ein*_*ica 0

我选择做的,以及我认为的,我们可以说,从声音设计角度来说,是实现一个名为 的类,memory_region它具有所有与类型无关的功能gsl::span(因此,例如,它没有开始() 或结束 ())。在我看来,它与字节范围不同——而且从结构上讲我永远不会把它们混淆

这是我的实现(它是与 DBMS 相关的 GPU 内核存储库和我正在开发的测试框架的一部分,因此是与 CUDA 相关的代码片段;它依赖于一些 GSL,在我的情况下,MS'es 的 gsl-lite 应该我想也可以)。