摘自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的规范中看到了:
typename std::add_lvalue_reference<T>::type operator*() const;
问题:
operator*
禁用unique_ptr
是否有意义且只有对于左值unique_ptr
s有效的取消引用? unique_ptr
取消引用吗?像这样:
//Make sure it is an lvalue.
typename std::add_lvalue_reference<T>::type operator*() const &;
注意:我不确定语法或正确性,我对* this的rvalue引用没有经验。
答案 0 :(得分:3)
我的问题是:使用
*this
的右值引用,这可以解决吗?
技术上是的。一种解决方案是为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表达式的尝试都会导致编译错误 - “使用已删除的函数”。
对于右值
operator*
禁止使用unique_ptrs
并且只对左值unique_ptrs
有效取消引用是否有意义?
并非总是如此。因此我怀疑库应该对unique_ptr
规范施加额外的限制,只是为了防止可能的滥用。
还有一些有效的用例可以让rvalue
unique_ptr
取消引用?
临时的生命周期在临时属于完整表达式的末尾结束。这意味着只要关联的unique_ptr
处于活动状态,从解除引用unique_ptr
获得的对象就是有效的,因此以下用例是有效的,如果operator*
则不可能。已被禁用为右值:
(*f()).foo();
// ^~~ unique_ptr is destroyed here
use(*f());
// ^~~ unique_ptr is destroyed here