如何安全地引用 std::vector 元素?
Posted
技术标签:
【中文标题】如何安全地引用 std::vector 元素?【英文标题】:How I can safely reference to an std::vector element? 【发布时间】:2021-05-16 22:31:34 【问题描述】:我想创建一个为其他结构保持更高状态的结构。
我尝试这样创建它,但我最近发现返回指向 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");
有什么好的和安全的方法来做到这一点?
【问题讨论】:
使用其他容器代替 std::vector? ^^ 例如std::list<T>
标准库有什么替代品吗?
我刚才提到了一个
你可以拥有share_ptr的vector并返回weak_ptr,这样你可以确保正确的引用。
【参考方案1】:
有什么好的和安全的方法来做到这一点?
保存这对夫妇(矢量参考,Foo
的索引),假设 Foo
s 只添加在后面。
加上一点语法糖:
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 FooProxymanyFoos, manyFoos.size()-1;
;
Live example
【讨论】:
【参考方案2】:你可以拥有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
【讨论】:
以上是关于如何安全地引用 std::vector 元素?的主要内容,如果未能解决你的问题,请参考以下文章
使用对 std::vector 的某些元素的引用,或这些元素在向量中的位置来迭代它们
如何告诉 auto 推断 vector<bool> 元素的非引用类型