5

假设我有

int foo(void* p, size_t size_in_bytes);

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

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

4

3 回答 3

5

这个问题不可能有一般的答案。

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

例如:

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

这听起来不像span<T>。听起来您应该有一个简单的聚合,其名称可以清楚地说明其含义:

struct memory_region
{
  void* p;
  size_t size_in_bytes;
};

你甚至可以给它一个成员函数来测试交叉点。如果您正在制作一个处理此类内存区域的系统,我可能会建议使用构造函数等更加封装的类类型。

函数采用什么类型应该解释数据的含义。这个意思最好是一般意义上的,但至少,它应该说明它对所讨论的功能意味着什么。


还有一件事:

span<uint8_t>等会暗示 foo 实际上期望字符

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


我的意思是说span<whatever>会暗示函数 expectwhatever的。

是的,对spans 的要求是传递给定大小的实际数组Ts。

于 2016-05-26T22:42:41.930 回答
1

C++ 标准化委员会的提议是,如果你想传递一个指向字节序列的指针(这通常是人们在传递时想要做void*的),那么你应该传递 a span<std::byte>,它依赖于一种新std::byte类型。但是,这需要对语言标准进行少量更改才能合法。

在当今的 C++ 中,您可以通过span<unsigned char>(typedef'd as you find most descriptive) 并获得相同的效果:访问字节序列。

于 2016-08-03T00:37:38.480 回答
0

我选择做的,以及我认为,容我们说,合理的设计,是实现一个名为 的类memory_region,它具有所有类型无关的功能gsl::span(例如,它没有开始() 或 end())。它与字节跨度不同,IMO - 我在结构上永远不会混淆它们

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

于 2016-09-19T20:45:39.860 回答