簡體   English   中英

weak_ptr C ++中的比較運算符

[英]Comparator operator in weak_ptr C++

我仍然是新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的比較器函數時會出現問題。 我在這里編譯程序

編輯:

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< for weak_ptr 但是,您確實有從weak_ptrStubClass的隱式轉換。 StubClass有一個operator< 所以這個函數無限地調用自己:因此是段錯誤。

來自inkooboo的當前接受的答案也將導致未定義的行為,可能導致崩潰。 由於weak_ptrs在程序執行期間過期(比測試用例更復雜),因此它們的順序將發生變化。 當在set兩個weak_ptrs之間發生這種情況時,該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

如果你想比較存儲在weak_ptr中的字符串,請執行以下操作:

bool operator<(StubClass d, StubClass c) 
{
    std::shared_ptr<std::string> a = d.b.lock();
    std::shared_ptr<std::string> b = c.b.lock();

    if (!a && !b)
        return false; 

    if (!a)
        return true;

    if (!b)
        return false;

    return *a < *b;
}

運行結果

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM