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

How to check if weak_ptr is empty (non-assigned)?

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

weak_ptr<int> w1;
weak_ptr<int> w2 = ...;

我了解以下针对未分配或过期的检查,但是是否有(更便宜?)仅针对未分配的检查?

if (!w.lock()) { /* either not assigned or expired */ }

使用 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();
}

输出

pointer  is expired
pointer is valid
pointer  is expired
Program ended with exit code: 0

您可以使用对 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);
}

这只会return true如果w{} "==" weak,其中"=="比较所有者,并且根据en.cppreference.com

The order is such that two smart pointers compare equivalent only if they are both empty or if they both own the same object, even if the values of the pointers obtained by get() are different (e.g. because they point at different subobjects within the same object).

由于默认构造函数构造了一个弱指针,这只能return true如果weak也是。如果weak已过期,这将不会returntrue

查看生成的程序集(经过优化),这似乎非常优化:

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

... 与检查 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

... 或 returning !weak.lock()(~80 行汇编)。