我想写一个函数:
- 接受一个指针作为参数
- 将长度作为参数
- 拥有指针指向的内存(例如,可能会释放它,或者在某些数据结构中为它构造一个 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/