如何返回向量的常量引用?

How to return const reference of a vector?

本文关键字:常量 引用 向量 何返回 返回      更新时间:2023-10-16

我有以下设置:

class A
{
public:
...
const std::vector<int>& getSomeData() const;
private:
std::map<SomeIdType, std::shared_ptr<SomeDataType> > m_someDataCollection;
}

答.cpp

const std::vector<int>& getSomeData(SomeIdType id) const
{
std::vector<int> rVal;
auto it = m_someDataCollection.find(id);
if (it != m_someDataCollection.end())
{
std::shared_ptr<SomeDataType> someData = it->second;
rVal = someData->getSomeDataVector(); // returns std::vector<int>
}
return  rVal;
}
int main()
{
SomeIdType id;
A a;
...
const std::vector<int>& data = a.getSomeData(id);
}

有一个对A.cpp中返回的局部变量的引用。

我不希望A::getSomeData()返回的向量在外面纵。

如何实现此目标,而不必返回对A.cpp中局部变量的引用?

如何返回向量的常量引用?

  1. 通过在函数以外的某个位置创建向量。由于在本例中它是一个成员函数,因此可以选择返回对成员的引用。或者,向量可以通过参数传递到函数中。
  2. 或者使用静态局部变量。在这种情况下,函数的所有入侵都将返回相同的向量。

任何非静态局部变量都不希望 A::getSomeData(( 返回的向量在外部作.e 具有自动存储,因此仅在函数结束之前存在。返回的对此类变量的引用将引用已销毁的向量。


也就是说,从您的示例中可以看出,您可能应该按值返回向量,而不是尝试返回引用。

我不希望 A::getSomeData(( 返回的向量在外面纵。

你还没有给出你想要那个的理由。你为什么要关心调用方如何处理你返回的向量?

我假设当在数据中找到 id 时,您希望返回对该 id 向量的引用,而不是复制整个向量。

对于空情况,您可以返回对始终为空的static局部变量的引用:

const std::vector<int>& getSomeData(SomeIdType id) const
{
auto it = m_someDataCollection.find(id);
if (it != m_someDataCollection.end())
{
return it->second->getSomeDataVector(); // returns const std::vector<int>&
}
else
{
static const std::vector<int> emptyVector;
return emptyVector;
}
}

将值转换为int后,它们不再引用原始数据,因此调用方无法对其进行修改。按值返回向量是安全的。如果向量包含指针或引用,则不安全。

std::vector<int> getSomeData(SomeIdType id) const
{
auto it = m_someDataCollection.find(id);
if (it != m_someDataCollection.end())
{
std::shared_ptr<SomeDataType> someData = it->second;
return someData->getSomeDataVector(); // returns std::vector<int>
}
return {};
}
const auto data = a.getSomeData(id);

如果您使用的是C++17,其中一种可能性也是使用std::optional。如果您找到了具有指定 ID 的元素,您将返回std::vector.否则,您将返回std::nullopt.在这种情况下,您的代码如下所示:

std::optional<std::vector<int>> getSomeData(SomeIdType id) const {
auto it = m_someDataCollection.find(id);
if (it != m_someDataCollection.end()) {
return it->second->getSomeDataVector();
}
else {
return {}; // or return std::nullopt;
}
}

然后你可以像这样使用它:

int main() {
SomeIdType id;
A a;
// ...
auto data = a.getSomeData(id);
if (data) {
// there is an item with the specified ID
// example of accessing the std::vector
for (auto const i : data.value().get()) {
// more code here ....
}
} else {
// there is NO item with the specified ID
}
}