【问题标题】:Unique Pointers and the push_back function [duplicate]唯一指针和 push_back 函数
【发布时间】:2015-02-02 22:35:06
【问题描述】:

我正在为一个结构创建一个 unique_ptr(效果很好):

std::unique_ptr<w9::Product> product (new w9::Product(desc[i].desc, price[j].price));

之后,我将该 unique_ptr 附加到向量成员函数中。

object += product;

重载 += 如下:

void operator+=(std::unique_ptr<Product> const &p) {
    object.push_back(&p);
}

问题是最后一点。将唯一 ptr 推回向量上的正确方法是什么?

编辑:

Object 是包含向量作为数据成员的模板类对象。 std::vector 列表

template <typename T>
class List {

    std::vector<T> list;
}

在这种情况下,T 将是一个 'unqiue_ptr'。

实际代码:

w9::List<w9::Product> merge(const w9::List<w9::Description> &desc, const w9::List<w9::Price>& price) {

w9::List<w9::Product> priceList;

for(int i = 0; i < desc.size(); i++){
    for(int j = 0; j < price.size(); j++){
        if(price[j].code == desc[i].code){
            std::unique_ptr<w9::Product> product (new w9::Product(desc[i].desc, price[j].price));
            product->validate();
            priceList += std::move(product);
        }
    }
}
return priceList;
}


void operator+=(std::unique_ptr<w9::Product> &&p) {
    list.push_back(std::move(p));
}

错误:

    ./List.h:41:12: error: no matching member function for call to 'push_back'
                list.push_back(std::move(p));
                ~~~~~^~~~~~~~~
w10.cpp:18:15: note: in instantiation of member function 'w9::List<w9::Product>::operator+=' requested here
                                priceList += std::move(product);
                                          ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:700:36: note: candidate function not viable: no
      known conversion from 'typename remove_reference<unique_ptr<Product, default_delete<Product> > &>::type' (aka 'std::__1::unique_ptr<w9::Product,
      std::__1::default_delete<w9::Product> >') to 'const value_type' (aka 'const w9::Product') for 1st argument
    _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);

【问题讨论】:

  • object的类型是什么?不要让我们猜测。
  • 它是一个模板类对象,包含一个向量作为数据成员。 std::vector 列表;
  • T 是什么? unique_ptr&lt;Product&gt;?或者是其他东西?您的问题需要包含所有相关信息
  • 结构的 unique_ptr。我很抱歉。*** 是的,你是对的。
  • 当您将unique_ptr 推入向量时,您希望发生什么?请记住,它被称为独特是有原因的。

标签: c++


【解决方案1】:

std::unique_ptr 是一个假定资源的唯一所有权的类。因此,它不支持复制语义。它的复制构造函数和复制赋值运算符被删除。为了共享一个唯一的对象,您需要转移所有权以保持该对象的“唯一性”。这是使用 move-semantics 完成的,它们在 std::unique_ptr 类的 move-constructor 和 move-assignment 运算符中实现。

您的operator+=() 方法并没有完全违反唯一所有权的概念,但它试图规避唯一对象实现的限制。这没有多大意义,也不直观。要么你想交换所有权,要么你想复制。如果您想复制对象,那么std::unique_ptr 可能不是您应该使用的对象。问问自己这个问题:product 是否想要拥有另一个对象或获得一个副本?

如果你的意图真的是共享一个独特的对象,你需要在你的函数中加入移动语义。您可以将右值引用绑定到参数并将其作为右值传递给push_back() 方法:

void operator+=(std::unique_ptr<Product>&& p) {
    object.push_back(std::move(p));
}

请注意,这是共享唯一对象的正确方法。一旦push_back() 从您的std::unique_ptr 移动,原始参数将不再拥有Product 资源的所有权。如果这不是您想要的,那么可以使用std::shared_ptr 来复制资源。

【讨论】:

  • 我删除了我的答案,因为这个更好。
  • 非常感谢。这是有道理的。但是将 (priceList += product) 传递给重载运算符会抛出:没有已知的从 'std::unique_ptr<:product>' 到 'std::unique_ptr<:product> &&' 我必须编辑接线员来电?
  • @SomeDeveloper 当它应该是一个右值引用时,您正在传递一个左值。使用std::move()x += std::move(ptr)
  • 这会引发一个非常丑陋的错误。让我用实际代码编辑我的问题。
  • @SomeDeveloper 那个丑陋的错误是什么?
猜你喜欢
  • 1970-01-01
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多