我想写一个函数:
现在,如果我想要1 + 2,我会使用gsl::span
。如果想要1 + 3,我会使用owner<T*>
。但是当我想要这三个时,我该怎么办?我应该通过owner<gsl::span<T>>
吗?还有别的吗?
答案 0 :(得分:1)
一种选择是定义自己的抽象基类来封装数据。类似的东西:
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
的隐式接口可以通过以下方式满足:
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}; }
};