我在编译以下代码时遇到问题:
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的deleter。MS扩展是否调用前一个值的deleter?
Update2:选中,是的,它删除了旧的ptr值,但不在swap
本身,而是在函数存在后(感谢James(
reset
正在调用旧ptr的deleter。MS扩展是否调用前一个值的deleter
CCD_ 5在调用中涉及的对象之间相互转移存储的指针的所有权。因此,myInternalUniquePtr
所拥有的指针与来自临时对象std::unique_ptr<Type>(new_ptr)
的指针进行交换,临时对象的生存期在其所属的完整表达式结束时结束。对于函数调用语句,这意味着在;
的点上销毁该临时指针,也就是说,最初存储在myInternalUniquePtr_
中的指针在语句执行后被释放(由该临时指针的析构函数(。VC++允许一个prvalue临时被一个非常值左值引用(这是一个不一致的特性(绑定,这一事实不应该影响上述行为。
替代品:
myInternalUniquePtr_->reset(new_ptr);
有效。然而,呼叫方不清楚MyMethod
内部发生了什么。一个更好的选择是强制调用方显式传递unique_ptr
,这表明函数拥有该指针的所有权,并且不应该指向(例如(数组。
void MyClass::MyMethod(std::unique_ptr<Type> new_ptr)
{
myInternalUniquePtr_ = std::move(new_ptr);
}