-1

次のようなコードがあります。

#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 */

しかし、Farm::addAnimal: メソッドでエラーが発生します。

「std::unique_ptr::unique_ptr(daq::Animal&)」の呼び出しに一致する関数がありません</p>

push_back メソッドには何を渡す必要がありますか?

4

1 に答える 1

3

Aはコンストラクターの引数としてポインターunique_ptrを受け入れますが、参照を渡しています。これは基本的に、コンパイラが伝えていることです: aから a を構築することはできません。std::unique_ptrdaq::Animal&

Animalで割り当てられた型のオブジェクトに生のポインターを渡すことができますnew。または (できれば)unique_ptrそのように構築されたものを渡し、の引数として提供するときにそこから移動するpush_back()必要があります。

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
}

s はコピーできないstd::move()ため、ここで使用する必要があります。そのため、それを呼び出すルーチンからそれを含むベクトルに の所有権を効果的に転送しています (この転送の中間体です)。unique_ptrpigaddAnimal()

于 2013-03-29T13:28:36.063 に答える