如何安全地引用std::vector元素

How I can safely reference to an std::vector element?

本文关键字:std 引用 vector 元素 何安全 安全      更新时间:2024-09-23

我想创建一个结构,为其他结构保持更高的状态。

我试着这样创建它,但我最近发现,返回一个指向std::vector元素的指针是不安全的,因为该指针可能会更改。

struct Foo {
std::string &context;
std::string content;
Foo(std::string &context, std::string content) : context(context), content(content) {}
}
struct Bar {
std::string context;
std::vector<std::string> manyFoos;
Foo* addFoo(std::string content) {
manyFoos.emplace_back(context, content);
return &manyFoos[manyFoos.size() - 1];
}
}
struct Example {
Bar bar;
Foo* fooA;
Foo* fooB;
Example() {
fooA = bar.addFoo("Hello");
fooB = bar.addFoo("World");
}
}

做这件事有什么好的、安全的方法?

有什么好的、安全的方法可以做到这一点?

保存耦合(向量引用,Foo的索引(,假设Foo只添加在后面。

加一点合成糖:

struct Bar {
std::string context;
std::vector<Foo> manyFoos;
struct FooProxy
{
std::vector<Foo>& foos;
std::vector<Foo>::size_type index;
operator Foo() { return foos[index]; }
};
auto addFoo(std::string content) {
manyFoos.emplace_back(context, content);
return FooProxy{manyFoos, manyFoos.size()-1};
}
};

实例

您可以拥有shared_ptr的向量&返回weak_ptr,这样可以确保正确引用

#include <iostream>
#include <vector>
#include <memory>
struct Foo {
std::string &context;
std::string content;
Foo(std::string &context, std::string content) : context(context), content(content) {}
};
struct Bar {
std::string context;
std::vector<std::shared_ptr<Foo>> manyFoos;
std::weak_ptr<Foo> addFoo(std::string content) {
auto foo = std::make_shared<Foo>(context, content);
manyFoos.emplace_back(foo);
return foo;
}
};
void printFoo(std::weak_ptr<Foo> foo)
{
// Here we are checking weak_ptr expiry
std::cout << (foo.expired() ? "Foo Expired" : foo.lock()->content) << std::endl;
}
int main() {
Bar bar;
std::weak_ptr<Foo> fooA;
std::weak_ptr<Foo> fooB;
fooA = bar.addFoo("Hello");
fooB = bar.addFoo("World");
printFoo(fooA);
printFoo(fooB);
// erase last element
bar.manyFoos.pop_back();
printFoo(fooB);
return 0;
}

输出:

Hello
World
Foo Expired