交换 unique_ptr's(非标准 Microsoft C++ 扩展)

swap unique_ptr's (non-standard Microsoft C++ Extension)

我在编译这段代码时遇到问题:

void MyClass::MyMethod(Type * new_ptr)
{
    myInternalUniquePtr_->swap(std::unique_ptr<Type>(new_ptr));
}

ReSharper 表示 Binding r-value to l-value reference is non standard Microsoft C++ extension。它似乎是正确的,因为我无法在 GCC 中编译它,例如。

我已将代码更改为:

void MyClass::MyMethod(Type * new_ptr)
{
    myInternalUniquePtr_->reset(new_ptr);
}

这可以接受吗?

更新: reset 正在调用旧 ptr 的删除器。 MS扩展是否调用了之前值的删除器?

Update2: 检查,是的,它删除了旧的 ptr 值,但不在 swap 本身,而是在函数存在之后(感谢 James)

reset is calling deleter of old ptr. Does MS extension call the deleter of the previous value?

std::unique_ptr::swap 在调用中涉及的对象之间相互转移存储指针的所有权。因此,myInternalUniquePtr 拥有的指针与来自临时对象 std::unique_ptr<Type>(new_ptr) 的指针交换,临时对象的生命周期结束于它所属的完整表达式的末尾。对于函数调用语句,这意味着在 ; 处销毁此临时文件,这意味着最初存储在 myInternalUniquePtr_ 中的指针在语句执行后被释放(通过该临时文件的析构函数) . VC++ 允许 prvalue temporary 被非 const 左值引用(这是一个不符合规范的特性)绑定的事实不应影响上述行为。

替换:

myInternalUniquePtr_->reset(new_ptr);

有效。但是,调用者不清楚 MyMethod 中发生了什么。一个更好的选择是强制调用者显式传递一个 unique_ptr,这使得该函数显然拥有该指针的所有权,并且它不应该指向,例如,一个数组。

void MyClass::MyMethod(std::unique_ptr<Type> new_ptr)
{
    myInternalUniquePtr_ = std::move(new_ptr);
}