2017-11-15 7 views
2

ユニークなptrsのベクトルを、私がクラスに保存したユニークなptrsのベクトルに移動したい。これはInserting a vector of unique_ptr into another vectorユニークなptrのベクトルを別のビアのメンバー関数に追加する

からの回答を追跡しようとしている

#include <iostream> 
#include <memory> 
#include <vector> 
using namespace std; 

class A 
{ 
public: 
    A() = default; 
}; 


class B 
{ 

public: 

    void AddAs(const vector<unique_ptr<A>>& vv) 
    { 

     vec.insert(vec.end(), 
      std::make_move_iterator(vv.begin()), 
      std::make_move_iterator(vv.end()) 
     ); 
    } 

    vector<unique_ptr<A>> vec; 
}; 


int main() {  
    vector<unique_ptr<A>> v; 
    for(int i=0; i<10; ++i) 
    { 
     v.push_back(make_unique<A>()); 
    } 
    B b; 
    b.AddAs(v); 

    return 0; 
} 

https://ideone.com/76iNIM

しかし、それはそれはコピー演算子を使用していると言うので、これはコンパイルされません:私はここで最小の例にこれを削減しました。

私はこれが愚かな質問だと確信していますが、私はC++を初めて使っています。コピーがどこにあるのか分かりません。

は、移動手段の変更を必要とするあなたは、あなたがconst参照によって渡されることを、ベクターから移動することはできません

答えて

1

ありがとうございます。だから、にその方法を変更します。

値渡し
void AddAs(vector<unique_ptr<A>>&& vv) 

も動作します:あなたがコードを呼び出す変更する必要が

void AddAs(vector<unique_ptr<A>> vv) 

注:

b.AddAs(std::move(v)); 

リーダーを示して、実際に良いですそのベクトルはから移動されます。

live example

+0

@NicolBolasなぜあなたは左辺値参照を削除しましたか?それは本当に読みやすいわけではありませんが、それでも動作します。 – Slava

+0

もちろん動作します。しかし、人々に悪い考えを与えるのは悪い考えです。左辺値参照からの移動はかなり*常に間違っています*。つまり、関数が呼び出されたサイトでは、オブジェクトが移動される兆候はありません。そして、オブジェクトからの移動は定義されていない状態になるため、後でそれを使用することは疑わしいです。それを防ぐことは 'std :: move'とrvalue references *が存在する理由の大きな部分です*。もう一つの理由は、もちろん、値を左辺値に渡すことはできません。 –

+0

"これは、関数が呼び出されたサイトでは、オブジェクトが移動される兆候がないことを意味します。はい、残念ながら、lvalue参照が渡されたほぼすべての呼び出しの場合です。メソッドはそれを変更すると考えられますが、呼び出し元サイトには何の指示もありません。しかし、これは一般的に左辺値参照を渡すことを禁止するのに十分な理由であるとは確信していません。 – Slava

関連する問題