如何检查weak_ptr是否为空(未分配)?

Zuz*_*uza 16 c++ weak-ptr c++11

有没有办法区分分配的(可能已过期的)weak_ptr和未分配的weak_ptr.

weak_ptr<int> w1;
weak_ptr<int> w2 = ...;
Run Code Online (Sandbox Code Playgroud)

我理解以下检查未分配或到期,但有没有(更便宜?)检查只有非转让?

if (!w.lock()) { /* either not assigned or expired */ }
Run Code Online (Sandbox Code Playgroud)

Hol*_*olt 22

您可以使用两个调用来owner_before检查与默认构造(空)弱指针的相等性:

template <typename T>
bool is_uninitialized(std::weak_ptr<T> const& weak) {
    using wt = std::weak_ptr<T>;
    return !weak.owner_before(wt{}) && !wt{}.owner_before(weak);
}
Run Code Online (Sandbox Code Playgroud)

只有在比较所有者和en.cppreference.com的true情况下w{} "==" weak,才会返回:"=="

顺序是两个智能指针只有当它们都是空的或它们都拥有相同的对象时才比较等价,即使get()获得的指针值不同(例如因为它们指向同一个中的不同子对象)宾语).

由于默认的构造函数构造一个弱的指针,这只能返回true如果weak也是空的.如果已过期,则不会返回.trueweak

查看生成的程序集(带优化),这看起来非常优化:

bool is_uninitialized<int>(std::weak_ptr<int> const&):
        cmp     QWORD PTR [rdi+8], 0
        sete    al
        ret
Run Code Online (Sandbox Code Playgroud)

...与检查相比weak.expired():

bool check_expired(std::weak_ptr<int> const&):
        mov     rdx, QWORD PTR [rdi+8]
        mov     eax, 1
        test    rdx, rdx
        je      .L41
        mov     eax, DWORD PTR [rdx+8]
        test    eax, eax
        sete    al
.L41:
        rep ret
Run Code Online (Sandbox Code Playgroud)

...或返回!weak.lock()(约80行组装).


Har*_*ngh 9

使用std::weak_ptr::expired()

#include <iostream>
#include <memory>

//declare a weak pointer
std::weak_ptr<int> gw;

void f()
{
    //check if expired
    if (!gw.expired()) {
        std::cout << "pointer is valid\n";
    }
    else {
        std::cout << "pointer  is expired\n";
    }
}

int main()
{
    f();
    {
        auto cre = std::make_shared<int>(89);
        gw = cre;
        f();
    } 

    f();
}
Run Code Online (Sandbox Code Playgroud)

输出

pointer  is expired
pointer is valid
pointer  is expired
Program ended with exit code: 0
Run Code Online (Sandbox Code Playgroud)