割り当てられている(期限切れの可能性がある)weak_ptrと割り当てられていないものを区別する方法はありますか?.
weak_ptr<int> w1;
weak_ptr<int> w2 = ...;
次の非割り当てまたは有効期限のチェックについて理解していますが、非割り当てのみの(安価な)チェックはありますか?
if (!w.lock()) { /* either not assigned or expired */ }
_owner_before
_への2つの呼び出しを使用して、デフォルトで作成された(空の)弱ポインターとの等価性をチェックできます。
_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
_が所有者を比較する_"=="
_の場合、および en.cppreference.com に従ってtrue
のみを返します。
順序は、get()によって取得されたポインタの値が異なる場合でも(たとえば、同じ内の異なるサブオブジェクトをポイントしているため)、2つのスマートポインタが両方とも空であるか、両方が同じオブジェクトを所有している場合にのみ、同等に比較されますオブジェクト)。
デフォルトのコンストラクターはemptyウィークポインターを構築するため、これはtrue
もemptyである場合にのみweak
を返すことができます。 true
の有効期限が切れている場合、これはではありませんweak
を返します。
生成されたアセンブリ(最適化あり)を見ると、これはかなり最適化されているように見えます。
_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行のアセンブリ)。
ウィークポインターをパラメーターとして受け入れ、ウィークポインターが期限切れの場合(または、あなたの場合のように割り当てられていない場合)は std :: bad_weak_ptr 例外を発生させる共有ポインターの作成を試みることができます。
#include <memory>
#include <iostream>
int main(){
// with an assigned pointer
std::shared_ptr<int> p1(new int(42));
std::weak_ptr<int> w1(p1);
try {
std::shared_ptr<int> p2(w1);
}
catch (const std::bad_weak_ptr& e) {
std::cout << e.what() << '\n';
}
// with a non assigned pointer
std::shared_ptr<int> p2(new int(42));
std::weak_ptr<int> w2;
try {
std::shared_ptr<int> p2(w2); // raises an exception
}
catch (const std::bad_weak_ptr& e) {
std::cout << "Ptr 2: " << e.what() << '\n';
}
}
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