ein*_*ica 5 c++ cpp-core-guidelines guideline-support-library
我想写一个函数:
现在,如果我想要 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;
};
Run Code Online (Sandbox Code Playgroud)
那么你的函数可能看起来像:
void foo(std::unique_ptr<DataHolder<int>> data) {
if (!data)
return;
for (auto v : data->get())
std::cout << v << " ";
}
Run Code Online (Sandbox Code Playgroud)
然后,调用者可以使用他们想要的任何容器来实现基类。多态性会产生很小的成本,但不是基于每个元素。
如果您不想为多态性付费,也许您可以让您的函数接受模板参数。
template<typename DataHolder>
void foo(DataHolder data) {
for (auto v : data())
std::cout << v << " ";
}
Run Code Online (Sandbox Code Playgroud)
其中隐式接口DataHolder可以通过以下方式满足:
struct VectorHolder {
std::vector<int> data;
gsl::span<const int> operator()() const { return data; }
};
Run Code Online (Sandbox Code Playgroud)
或者如果您确实不想使用vector. 你可以使用这样的东西(按照@utnapistim的建议):
struct ArrayHolder {
std::unique_ptr<int[]> data;
ptrdiff_t length;
gsl::span<const int> operator()() const { return {data.get(), length}; }
};
Run Code Online (Sandbox Code Playgroud)