C++ 具有唯一_ptr-s的向量

C++ 具有唯一_ptr-s的向量,c++,c++11,move-semantics,C++,C++11,Move Semantics,我有这样的代码: #include <memory> #include <vector> namespace daq { class Animal { public: Animal(){}; }; class Pig : public Animal { public: Pig() : Animal () {}; }; class Farm { public: void addAnimal(Animal& animal) {

我有这样的代码:

#include <memory>
#include <vector>

namespace daq
{

class Animal
{
public:
    Animal(){};
};

class Pig : public Animal
{
public:
    Pig() : Animal () {};
};

class Farm
{
public:
    void addAnimal(Animal& animal)
    {
        mAnimals.push_back(std::unique_ptr<Animal>(animal)); // error
    }

private:
    std::vector<std::unique_ptr<Animal>> mAnimals;
};
} /* namespace daq */
#包括
#包括
名称空间数据采集
{
类动物
{
公众:
动物{};
};
猪类:公共动物
{
公众:
猪():动物(){};
};
阶级农场
{
公众:
动物(动物和动物)
{
mAnimals.push_back(std::unique_ptr(动物));//错误
}
私人:
std::矢量模型;
};
}/*名称空间daq*/
但是我在方法Farm::addAnimal中得到错误:

调用“std::unique\u ptr::unique\u ptr(daq::Animal&)”时没有匹配的函数


我应该向push_-back方法传递什么?

A
unique\u ptr
接受指针作为构造函数参数,但您正在传递引用。这基本上就是编译器告诉您的:您不能从
daq::Animal&
构造
std::unique\u ptr

您可以传递一个原始指针,指向分配了
new
Animal
类型的对象,或者(最好)传递一个以这种方式构造的
unique\u ptr
,并在将其作为
push\u back()的参数提供时从中移出:

void addAnimal(std::unique_ptr&&animal)
//                                    ^^
//这是为了清楚地表明
//您的意图是绑定到一个对象
//客户想要离开。事实并非如此
//这里特别需要(不需要唯一的ptr
//可复制),但它使您的界面
//更明确地说。[贷记sehe]
{
推回(标准::移动(动物));//好
}
int main()
{
daq:农场;
std::unique_ptr pig(新的daq::pig());
farm.addAnimal(std::move(pig));//好的
}

您必须在此处使用
std::move()
,因为
unique\u ptr
s是不可复制的,所以您实际上是在将
pig
的所有权从调用它的例程转移到包含它的向量(
addAnimal()
是此转移的中间层).

您应该传递一个指针。如果您希望存储通过引用接收的项的动态副本(std::unique_ptr),则必须使元素类型(Animal)可克隆。但是出于样式的原因,将参数作为右值引用“接收”(记录移动语义)不是更好吗<代码>无效添加动物(标准::唯一动物)
@sehe:你的意思是,接收一个
动物&&
并执行
farm.addAnimal(std::move(Animal))
?我的意思是更改现有的
addAnimal(而不是添加另一个重载)@sehe:这就是我的意思:更改现有的
addAnimal()
以接收一个
动物&
,并通过执行
farm.addAnimal(std::move>来调用它(动物)
。这就是你的建议吗?@sehe:我想说的是,这会破坏引用语义(尽管不清楚这里是否需要它)。客户端可能希望保留一个指向它添加到农场的动物的观察指针。另一方面,如果不需要引用语义,则
mAnimals
可以是
vector
,并且
addAnimal()
的参数可以完美地转发到
mAnimals
void addAnimal(std::unique_ptr<Animal>&& animal)
//                                    ^^
//                                    This is to make it absolutely clear that
//                                    your intention is to bind to an object
//                                    the client wants to move from. It is not
//                                    especially needed here (unique_ptr is not
//                                    copyable), but it makes your interface
//                                    more explicit about it. [Credits to sehe]
{
    mAnimals.push_back(std::move(animal)); // OK
}

int main()
{
    daq::Farm farm;
    std::unique_ptr<daq::Animal> pig(new daq::Pig());
    farm.addAnimal(std::move(pig)); // OK
}