C++ copy map to vector with std::move
Asked Answered
H

3

4

I'm relativly new to C++ and this might be a foolish question but I'm trying to understand rValue and lValue references at the moment and this came to my mind:

Let's say we have a map (which comes from a database or whatever) and we want to copy all values of it to a vector.

void insertItems(std::vector<std::string>& v)
{
    std::map<int, std::string> names = loadFromDb();

    for (auto& kv : names )
    {
        v.push_back(std::move(kv.second));
    }
}

Is it right to use std::move here? std::string provides an move constructor and (maybe not for string but for larger objects) the move constructor is much faster than the copy constructor. Also we know that we do not use the items of the map somewhere else and they go out of scope as soon as we leave the function. So is my presumption right?

I can't see a contradiction in my thoughts but it's a complicated topic and I'm afraid to miss something. P.S.: I think the question name is not the best. If you have a better one feel free to edit it.

Hesiod answered 16/2, 2017 at 18:55 Comment(3)
Implementation is correct. a v.reserve is an other optimization to do.Sherr
Oh and remember that v is not a pointer.Inning
Oh yes thank you you are absolutely right. I've corrected thatHesiod
Y
8

Is it right to use std::move here?

If you are sure that you won't access the moved values in the future, yes.


You might also want to use std::vector::reserve to preallocate the required space in v.

v.reserve(v.size() + names.size());
Yangyangtze answered 16/2, 2017 at 18:57 Comment(5)
I think you mean v.reserve(v.size() + names.size()); since v may not be empty initially.Race
If I don't use reserve every time I insert a new values a copy of the vector will be created?Hesiod
@Cilenco: std::vector internally uses a pointer to an heap-allocated array to store values. The array has a fixed size. When the array is full, a reallocation is performed and all the values in the previous array are moved to the new one. Reserving in advance prevents that from happening (when you know how much elements you're going to push in the vector).Yangyangtze
@Hesiod Another note on that. Every implementation is potentially different but generally vectors grow exponentially. Reserve is good because it means you'd suffer at most one reallocation (assuming you know how much to reserve) but it is not the case that for every single push_back you perform you would have to grow if you did not reserve(aka it isn't the end of the world if you don't know how much to reserve).Moravia
it's a good habit to get in to use emplace(_back) instead of push(_back) where possible. While on a vector it's not a huge deal, with other data types it can be a pretty big win.Picture
R
3

Is it right to use std::move here?

Yeah. The code looks fine.

Race answered 16/2, 2017 at 18:57 Comment(0)
I
1

In the case you show then yes moving will be fine as you won't use the map or its values later.

If the map wasn't a value (like if it was a reference), or you need to use the values in it later, then it's wrong.

Inning answered 16/2, 2017 at 18:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.