有没有一种方法可以区分已分配(可能已过期)的 weak_ptr 和未分配的 one。
weak_ptr<int> w1;
weak_ptr<int> w2 = ...;
我明白以下代码是用于查找未被赋值或过期的情况,但是否有一种(更便宜的)方法只检查未被赋值的情况?
if (!w.lock()) { /* either not assigned or expired */ }
您可以使用两个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);
}
只有当w{} "==" weak
时,此代码才会返回true
。其中"=="
是对所有者进行比较,根据en.cppreference.com:
顺序是这样的:仅当两个智能指针都为空或它们拥有相同的对象时,它们才会相等,即使通过get()获取的指针值不同(例如,因为它们指向同一对象内的不同子对象)。
由于默认构造函数构造了一个空的弱指针,因此只有当weak
也是空的时,此代码才会返回true
。如果weak
已过期,则不会返回true
。
查看生成的汇编代码(经过优化后),此代码似乎很优化:
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
... 或者 返回!weak.lock()
(约80行汇编代码)。
Using 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
expired
,但据我所知没有办法区分它们的不同。 - NathanOliverstd::optional
的某些功能。 - AndyG