31

std::vector<unique_ptr<int> >構築中のクラスに aの所有権を譲渡する適切な方法は何ですか?

以下は、私がやりたいことのコード表現です。ベクトルをコンストラクターに値または参照で渡すかどうかは正しくなく (コンパイルされません)、「一意性」に違反していることに気付きました。Foo がベクターの新しい所有者になり、呼び出し元の関数が所有権を放棄するようにします。これを行うには、コンストラクターを使用する必要がありstd::unique_ptr<std::vector<std::unique_ptr<int> > >ますか?

フー。

class Foo
{
public:
  Foo(vector<std::unique_ptr<int> > vecOfIntPtrsOwnedByCaller);

private:
  vector<std::unique_ptr<int> > _vecOfIntPtrsOwnedByFoo;
}

Foo.cpp

Foo::Foo(std::vector<std::unique_ptr< int> > vecOfIntPtrsOwnedByCaller)
{
    _vecOfIntPtrsOwnedByFoo = vecOfIntPtrsOwnedByCaller;
}

どんな助けでも大歓迎です-私はこれを行う正しい方法を探してネットを精査しました。ありがとう!

4

1 に答える 1

28

std::unique_ptr<T>はコピー不可ですが移動可能なタイプです。移動専用タイプstd:vector<T>std::vector<T>移動専用にします。コンパイラにオブジェクトを自動的に移動させるには、move-construction または move-assignment の右辺値が必要です。コンストラクター内では、オブジェクトvecOfIntPtrsOwnedByCallerは左辺値ですが、その名前にもかかわらず、既にints を指しているオブジェクトを所有しています。呼び出し元がオブジェクトを作成したときに、それらは呼び出し元から「盗まれました」。左辺値から移動するには、次を使用する必要がありますstd::move()(または同等のもの):

Foo::Foo(std::vector<std::unique_ptr<int>> vecOfIntPtrsOwnedByCaller)
{
    _vecOfIntPtrsOwnedByFoo = std::move(vecOfIntPtrsOwnedByCaller);
}

または、好ましい

Foo::Foo(std::vector<std::unique_ptr<int>> vecOfIntPtrsOwnedByCaller)
    : _vecOfIntPtrsOwnedByFoo(std::move(vecOfIntPtrsOwnedByCaller))
{
}

後者のアプローチでは、最初にメンバーをデフォルト構築してからそれに移動代入することを回避し、代わりにメンバーを直接移動構築します。引数をr値参照にすることもあると思いますが、これは必須ではありません。

Foor値にバインドできるものからのみタイプのオブジェクトを構築できることに注意してください。

int main() {
    Foo f0(std::vector<std::unique_ptr<int>>()); // OK
    std::vector<std::unique_ptr<int>> v;
    Foo f1(v); v// ERROR: using with an l-value
    Foo f2{v}; v// ERROR: using with an l-value
    Foo f3 = v; // ERROR: using with an l-value
    Foo f4(std::move(v)); // OK: pretend that v is an r-value
}
于 2013-08-16T22:37:35.863 に答える