【问题标题】:Should I replace (void*, size) with a GSL span?我应该用 GSL 跨度替换 (void*, size) 吗?
【发布时间】:2016-05-26 21:55:58
【问题描述】:

假设我有

int foo(void* p, size_t size_in_bytes);

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

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

【问题讨论】:

  • 制作正确类型的函数模板?
  • template<typename T> int foo(T&&) 可以。
  • @Jarod42:您假设存在正确的类型。如果该函数检查缓冲区是否与我的内存空间中的某个区域相交,例如映射到一个文件,该怎么办?
  • 什么? span 看起来像是string_view 的 GSL 通用版,完全不适用于这种情况。
  • @GuillaumeRacicot 为什么是转发参考? OP 只想要一个指针和一个大小,或者一些可以代表它的 C++ 东西,但 T&& 可以是任何东西(右值引用、左值引用、指针等)

标签: c++ guideline-support-library


【解决方案1】:

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

对于一个函数来说,它需要 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> 意味着函数期望whatever 的。

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

【讨论】:

    【解决方案2】:

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

    在当今的 C++ 中,您可以通过 span<unsigned char>(您发现最具描述性的类型定义)并获得相同的效果:访问字节序列。

    【讨论】:

    • 你能链接到那个提案吗?
    • Ping 我之前的评论。
    【解决方案3】:

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

    这是我的implementation(它是与 DBMS 相关的 GPU 内核的存储库和我正在开发的测试框架的一部分,因此是与 CUDA 相关的 sn-p;它取决于一些 GSL,在我的情况下是 gsl我认为 MS'es 的 -lite 也应该没问题)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-06
      • 2012-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多