2017-04-12 10 views
2

私は、コードの打撃を試みたinserterback_inserterは同じlst3を作るが、私は新しい要素がlst3.begin()前の位置に挿入されなければならないようinserter{4,3,2,1}のリストを作るべきだと思います。なぜ彼らは同じ結果を出しますか? ありがとう!C++の `inserter`のメカニズムは何ですか?

int main() { 
    list<int> lst = {1,2,3,4}; 
    list<int> lst3; 
    // copy(lst.cbegin(), lst.cend(), inserter(lst3, lst3.begin())); 
    copy(lst.cbegin(), lst.cend(), back_inserter(lst3)); 
    for_each(lst.cbegin(), lst.cend(), [] (const int i) {cout<<i<<endl;}); 
    return 0; 
} 
+1

'std :: copy'の前に' lst3'に1つの要素(-1としましょう)を加えて、何が起こるかを見てください。 'initter(lst3、lst3.begin()) 'はあなたに' 1 2 3 4 -1'と 'back_inserter'を与えます-1.1 2 3 4' – Raxvan

+0

IIUC、混乱は' lst3 .begin()を毎回実行します。 cppreferenceは 'inserter'の例でそれを説明しています:http://en.cppreference.com/w/cpp/iterator/inserter – chris

答えて

0

std::inserter関数は、関数に渡される引数からstd::insert_iteratorオブジェクトを作成します。

あなたの経験があるため二つのことである問題:

  • 最初はイテレータが第二は、容器が空になったとき、そのbeginイテレータはそのに等しいということである
  • にコピーされるということですendイテレータ。

したがってstd::insert_iteratorオブジェクトがリストend反復子のコピーを持っているので、リストの末尾に挿入します。

既存のリストの始めから反復し、常に最後に挿入すると、効果は反復される順番で要素が挿入されるstd::back_inserterを使用する場合とまったく同じになります。

+0

まあ、要素は常に元の順序で挿入されますよね? OPは、彼らが逆の順序で挿入されていない理由を尋ねるが、決して起こっていない。 –

0

表示される動作は、std::inserter()の場合は正しいです。

あなたが期待している動作、つまりは常にがフロントに挿入されています。これはstd::front_inserter()を使用した場合の動作です。

0

新しい要素がlst3.begin前の位置に挿入する必要があります ()

あなたはこの同等の想像している:

copy(lst.cbegin()+0, lst.cbegin()+1, inserter(lst3, lst3.begin())); 
copy(lst.cbegin()+1, lst.cbegin()+2, inserter(lst3, lst3.begin())); 
copy(lst.cbegin()+2, lst.cbegin()+3, inserter(lst3, lst3.begin())); 
copy(lst.cbegin()+3, lst.cbegin()+4, inserter(lst3, lst3.begin())); 

(ふりをそれらの+操作があろうとリストイテレータで作業してください)

私はあなたがそれを考える理由を知ることができます。リストは、具体的になりやすいではありません。我々はそれができないことを知っている—あなたは、lst3.begin()inserterに、このイテレータが/保存されたキャッシュされ、繰り返し使用されていない提供(瞬間のための一般的なケースを考えているので

このようなイテレータは、挿入操作ごとに無効になる可能性があります。

代わりに、イテレータは各操作の後にインクリメントされます。

cppreference explains this:各のstd :: insert_iterator ::演算子は=

実際にターゲットイテレータを更新するため、

シーケンスコンテナに挿入し、挿入ポイントは、私たち自身のためにこれを見ることができ、前進しますthe cppreference insert_iterator::operator= pageから。

最終的な結果は以下のように、あなたが実際に直線的に挿入していることを、左から右への順序である:

copy(lst.cbegin()+0, lst.cbegin()+1, inserter(lst3, lst3.begin())); 
copy(lst.cbegin()+1, lst.cbegin()+2, inserter(lst3, lst3.begin()+1)); 
copy(lst.cbegin()+2, lst.cbegin()+3, inserter(lst3, lst3.begin()+2)); 
copy(lst.cbegin()+3, lst.cbegin()+4, inserter(lst3, lst3.begin()+3)); 

(これら +操作は、リストイテレータ上で動作することをふり)

この動作は実際にはより直感的です。 ソース範囲の全体が、元の順序で、開始位置lst3.begin()に挿入されています。

関連する問題