[英]Preventing unsafe dereferencing of std::unique_ptr
摘自cppcon2015的幻燈片:
unique_ptr<A> f() {
auto a = make_unique<A>();
return a;
}
//Why does this even compile?
const A & dangling = *f();
//BOOM!!!
use(dangling);
我的問題是:對於* this的rvalue引用,這可以解決嗎?
我在cppreference的spec中看到:
typename std::add_lvalue_reference<T>::type operator*() const;
題:
operator*
為rvalue unique_ptr
而且只有對於左值unique_ptr
s有效的解除引用才有意義嗎? unique_ptr
解除引用嗎? 像這樣:
//Make sure it is an lvalue.
typename std::add_lvalue_reference<T>::type operator*() const &;
注意:我不確定語法或正確性,我對* this的rvalue引用沒有經驗。
我的問題是:對於
*this
rvalue引用,這可以解決嗎?
技術上是的。 一種解決方案是為rvalues引入一個額外的(刪除的)重載:
typename std::add_lvalue_reference<T>::type operator*() const&& = delete;
// ~~~~~~~~~~~~~~~^
並通過添加ref-qualifier來修改現有的:
typename std::add_lvalue_reference<T>::type operator*() const&;
// ~~^~~
由於rvalues強烈傾向於被rvalue引用綁定,因此任何嘗試取消引用涉及unique_ptr
的rvalue表達式都會導致編譯錯誤 - “使用已刪除的函數”。
為rvalue
unique_ptrs
禁用operator*
並且只對lvalueunique_ptrs
有效取消引用是否有意義?
不總是。 因此,我懷疑庫應該對unique_ptr
規范施加額外的限制,只是為了防止可能的誤用。
還有一些有效的用例可以保持rvalue
unique_ptr
解除引用嗎?
臨時的生命周期在臨時屬於完整表達式的末尾結束。 這意味着只要關聯的unique_ptr
處於活動狀態,從解除引用unique_ptr
獲得的對象就是有效的,因此下面的用例是有效的,如果對rvalues禁用operator*
則不可能:
(*f()).foo();
// ^~~ unique_ptr is destroyed here
use(*f());
// ^~~ unique_ptr is destroyed here
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.