3

I want to write functions to add items. addItem and addItems each with a move variant. The latter accepts two input iterators. To add a single item I can overload the signature with rvalue references. But how do I overload a template function to work with move semantics?

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

Is it possible to have a single name for a function and to differentiate between the input iterators?

3
  • 2
    Have you looked into std::make_move_iterator? Commented Sep 6, 2017 at 16:10
  • I have, but I dont understand how to overload the function to accept both move and non-move iterators. Commented Sep 6, 2017 at 16:30
  • @ManuelSchneid3r: Your current signature accepts all iterators Commented Sep 6, 2017 at 19:54

1 Answer 1

4

Since you are using iterator to insert to your list, the most straightforward solution would be to use move iterators. With move iterators, you don't need to change your template function addItems. The move iterators will move the referred element into the new container:

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

Alternatively, you could provide a move insert function, which uses the std::move algorithm:

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

This overload will move each elements to thelist container. The std::move algorithm is meant to be used with normal, non const iterators. The move item function is used like that:

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())
);
Sign up to request clarification or add additional context in comments.

4 Comments

What if I dont pass move iterators? I need both of them.
@ManuelSchneid3r both what? Is there a way I can improve this answer?
Well I can overload the addItem function by passing a reference in one function and a rvalue reference in the other function. Thats not the case with a templatet function. So I want to understand how I can overload this addItems function for both r- and lvalue references just like in the addItem function. What happens if I pass a regular iterator (non move) to your moveItems function?
@ManuelSchneid3r iterator are not passed by reference. Iterator are passed by value. There's no overload to do. If you were to take a container as parameter, I would also take the container by value and move the contained elements.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.