c++ - 我如何使用 gsl::span 并指示所有权?

标签 c++ cpp-core-guidelines guideline-support-library

我想写一个函数:

  1. 接受一个指针作为参数
  2. 将长度作为参数
  3. 拥有指针指向的内存(例如,可能会释放它,或者在某些数据结构中为它构造一个 unique_ptr 等)

现在,如果我想要 1+2,我会使用 gsl::span .如果想要 1+3 我会使用 owner<T*> .但是当我想要这三个时我该怎么办?我应该通过 owner<gsl::span<T>> 吗? ?还有别的吗?

注意事项:

  • 你不能假设指针在堆中。
  • std::vector要求太多了。该函数不应要求调用者构造 std::vector .

最佳答案

一种选择是定义您自己的抽象基类来封装数据。像这样的东西:

template<typename T>
class DataHolder {
public:
  virtual ~DataHolder() = default;
  virtual gsl::span<T> get() const = 0;
};

那么你的函数看起来像这样:

void foo(std::unique_ptr<DataHolder<int>> data) {
  if (!data)
    return;
  for (auto v : data->get())
    std::cout << v << " ";
}

然后调用者可以使用他们想要的任何容器来实现基类。多态性会有少量成本,但不是基于每个元素。

如果你不想为多态性付出代价,也许你可以让你的函数接受一个模板参数。

template<typename DataHolder>
void foo(DataHolder data) {
  for (auto v : data())
    std::cout << v << " ";
}

DataHolder 的隐式接口(interface)可以通过以下方式满足:

struct VectorHolder {
    std::vector<int> data;
    gsl::span<const int> operator()() const { return data; }
};

或者如果您真的不想使用vector。你可以使用这样的东西(正如@utnapistim 所建议的):

struct ArrayHolder {
    std::unique_ptr<int[]> data;
    ptrdiff_t              length;
    gsl::span<const int> operator()() const { return {data.get(), length}; }
};

关于c++ - 我如何使用 gsl::span 并指示所有权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39827851/

相关文章:

c++ - 将 std::string 中的一段文本向左移动 X 个字符

c++ - gsl::not_null<T*> 与 std::reference_wrapper<T> 与 T&

c++ - 您是否打算从违反契约(Contract)中恢复过来?

c++ - 与 --N/--no-buffer 等效的 LIBCURL 是什么?

c++ - 如何使用命令行在 C++ 中编译和链接分离的 .h 和 .cpp 文件?

c++ - 当索引不是整数常量表达式时,不要使用数组下标;使用 gsl::at() 代替

c++ - 将 gsl::zstring_view 与 C API 结合使用

c++ - Ensures() - 指南支持库

c++ - 窄播有什么作用?

C++ `digits10` 对于 IEEE float 是 6,但第一个不可表示的整数已经有 8 位数字?