一种选择是定义自己的抽象基类来封装数据。就像是:
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}; }
};