gpt4 book ai didi

c++ - weak_ptr C++ 中的比较运算符

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:20:16 24 4
gpt4 key购买 nike

我在新的 STL 成员中还是个新手。谁能指出为什么这段代码会出现段错误?

#include<memory>
#include<stdio.h>
#include<map>
#include<set>
#include<string>
using namespace std;
struct StubClass
{
weak_ptr<string> b;
int c;
friend bool operator==(StubClass x,StubClass y);
friend bool operator<(StubClass x,StubClass y);
StubClass(weak_ptr<string> x):b(x){c=5;}
};
bool operator==(StubClass d,StubClass c) { return d.b==c.b;}
bool operator<(StubClass d,StubClass c) { return d.b<c.b; }


int main()
{
shared_ptr<string> spPtr(new string("Hello"));
weak_ptr<string> wpPtr(spPtr);
StubClass hello(wpPtr);
set<StubClass> helloSet;
helloSet.insert(hello);
if(helloSet.find(StubClass(wpPtr))!=helloSet.end()) printf("YAYA");
else puts("Bye");
}

错误在行

if(helloSet.find(StubClass(wpPtr))!=helloSet.end()) printf("YAYA");

更多研究表明调用 StubClass 的比较器函数时存在问题。我正在编译程序 here

编辑:

bool operator==(StubClass d,StubClass c) { return d.b.lock()==c.b.lock();}
bool operator<(StubClass d,StubClass c) { return d.b.lock()<c.b.lock(); }

这解决了问题。我应该阅读更多内容。:(无论如何,社区中的任何人都可以解释第一个代码给出 SIGSEGV 的原因。我最终弄明白了,但仍然是一个很好的解释不会有什么坏处。 :)

最佳答案

您的原始代码出现段错误是因为您不小心设置了无限递归:

bool operator<(StubClass d,StubClass c) { return d.b<c.b; }

没有operator<对于 weak_ptr .但是,您确实有来自 weak_ptr 的隐式转换至 StubClass .和 StubClass有一个 operator< .所以这个函数无限期地调用自己:因此是段错误。

目前接受的来自 inkooboo 的答案也会导致未定义的行为,可能导致崩溃。作为weak_ptrs在你的程序执行期间过期(比你的测试用例更复杂),那么它们的顺序就会改变。当这发生在两个 weak_ptrs 之间时在set , set将被损坏,可能导致崩溃。但是有一种方法可以使用 owner_less 解决这个问题这是专门为这个用例设计的:

bool operator==(const StubClass& d, const StubClass& c)
{
return !owner_less<weak_ptr<string>>()(d.b, c.b) &&
!owner_less<weak_ptr<string>>()(c.b, d.b);
}
bool operator<(const StubClass& d, const StubClass& c)
{
return owner_less<weak_ptr<string>>()(d.b, c.b);
}

或者,如果您愿意,也可以使用成员函数 owner_before 对其进行编码.两者是等价的:

bool operator==(const StubClass& d, const StubClass& c)
{
return !d.b.owner_before(c.b) && !c.b.owner_before(d.b);
}
bool operator<(const StubClass& d, const StubClass& c)
{
return d.b.owner_before(c.b);
}

使用这些函数,即使是一个weak_ptr过期而另一个没有,他们的顺序保持稳定。因此,您将拥有一个定义明确的 set .

关于c++ - weak_ptr C++ 中的比较运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11034683/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com