2017-09-06 4 views
3

アイテムを追加する関数を記述したいと思います。 addItemとaddItemsのそれぞれに移動バリアントがあります。後者は2つの入力イテレータを受け入れます。 1つのアイテムを追加するには、rvalue参照で署名をオーバーロードすることができます。しかし、私はどのように移動セマンティクスで動作するようにテンプレート関数をオーバーロードするのですか?移動セマンティクスイテレータとテンプレートの使用方法

void addItem(const shared_ptr<Item>& item, uint score) { 
    // code that copies the shared_ptr… 
} 

void addItem(shared_ptr<Item>&& item, uint score) { 
    // code that moves the shared_ptr… 
} 

template<typename Iterator> 
void addItems(Iterator begin, Iterator end) { 
    /* 
    * What to do here to take both move and normal iterators? 
    * Since I cannot overload by signature I dont know how to 
    * differentiate between move and non move iterators 
    */ 
} 

関数には1つの名前を付けることができますが、入力イテレータを区別することはできますか?

+2

あなたは[ 'のstd :: make_move_iterator'](http://en.cppreference.com/w/cpp/iterator/make_move_iterator)に見たことがありますか? – CoryKramer

+0

私は持っていますが、移動と非移動のイテレータの両方を受け入れる関数をオーバーロードする方法を理解していません。 – ManuelSchneid3r

+0

@ ManuelSchneid3r:あなたの現在の署名は_all_イテレータを受け入れます –

答えて

4

リストに挿入するためにイテレータを使用しているため、最も簡単な解決策は、イテレータを移動することです。イテレータを移動すると、テンプレート関数addItemsを変更する必要はありません。

template<typename Iterator> 
void moveItems(Iterator begin, Iterator end) { 
    std::move(begin, end, thelist.end()); 
} 

このオーバーロードは、各要素を移動します:あなたはstd::moveアルゴリズムを使用する移動挿入機能を、提供することができ、また

// Same function as before 
addItems(
    std::make_move_iterator(someList.begin()), 
    std::make_move_iterator(someList.end()) 
); 

:移動イテレータは、新しいコンテナに呼ば要素を移動しますthelistコンテナ。 std::moveアルゴリズムは、通常の非constイテレータで使用するためのものです。移動アイテム機能は、そのように使用されます。

std::vector<int> vec{1, 2, 3}; 

// move each ints into the new container 
moveItems(vec.begin(), vec.end()); 

// With your old function, move semantics 
// can still be applied with move Iterators 
addItems(
    std::make_move_iterator(vec.begin()), 
    std::make_move_iterator(vec.end()) 
); 
+0

イテレータを渡すことはできません。私はそれらの両方が必要です。 – ManuelSchneid3r

+1

@ ManuelSchneid3rどちらも?この回答を改善できる方法はありますか? –

+0

もう一つの関数で参照を渡し、他の関数でrvalue参照を渡すことで、addItem関数をオーバーロードすることができます。 Templatet関数の場合はそうではありません。ですから、addItem関数のように、r値とlvalue参照の両方に対してこのaddItems関数をどのようにオーバーロードできるかを理解したいと思います。 moveItems関数に通常のイテレータ(非移動)を渡すとどうなりますか? – ManuelSchneid3r

関連する問題