如何表示返回一个向量或对一个已分配的向量的引用?



我有一个函数,它应该返回一个新向量或对现有向量的引用。我之所以需要这样做,是因为在某些情况下,向量已经被别人创建并拥有,我想避免复制它。

一个选项是返回std::variant<std::vector<int>, std::vector<int>&>,但随后调用者需要添加逻辑来识别返回的内容。(不允许)

另一个选择是使用包装器类(为了清晰起见,我避免使用模板):

class VectorContainer {     
VectorContainer() : v(std::vector<int>()), v_ptr(nullptr) {}
VectorContainer(std::vector<int>& ref): v_ptr(&ref) {}
std::vector<int>& get() {
if (v_ptr == nullptr) return v;
return *v_ptr;
}
private:
std::vector<int> v;
std::vector<int>* v_ptr;
};
VectorContainer f();

引用保证比VectorContainer更有效,另外,拥有vector的代码是固定的,你不能改变它。我相信这是不允许使用共享指针之类的东西的。

标准库中是否存在现有的类?如果没有,我该怎么做呢?

您的方法很接近,但我建议让引用始终指向适当的对象:

class VectorContainer {
private:
std::vector<int> v_own;
public:
std::vector<int>& data;
VectorContainer(std::vector<int> own) : v_own{std::move(own)}, data{v_own} {}
VectorContainer(std::vector<int>& ref) : v_own{}, data{ref} {}
~VectorContainer() = default;
VectorContainer& operator=(VectorContainer const&) = delete;
VectorContainer& operator=(VectorContainer&&) = delete;
VectorContainer(VectorContainer const& from) : 
v_own{from.v_own},
data{(&from.v_own == &from.data)?v_own:from.data} {
}
VectorContainer(VectorContainer&& from) :
v_own{std::move(from.v_own)},
data{(&from.v_own == &from.data)?v_own:from.data} {
}
};

这里您总是访问data,或者您可以隐藏data并添加这样的包装器:

std::vector<int>& operator*() const {
return data;
}
// or a conversion operator to std::vector<int>&

无论哪种方式,是否存在间接都是对用户隐藏的。你总能看到参考资料。注意,拖拽一个空向量实际上没有任何开销。初始化是最小的。

的例子:

struct Example {
std::vector<int> v{1,2,3};
VectorContainer example(bool const b) {
if (b)
return VectorContainer(std::vector{0}); // new vector
else
return VectorContainer(v); // reference to v
}
};

最新更新