Reputation: 226
I have the following code in my project at the moment :
std::vector<int> vectorOfFirsts;
std::set<double> setOfSeconds;
std::list<std::pair<int,double>> cachedList;
// do something to fill the list
for (const auto& pair : cachedList)
{
vectorOfFirsts.push_back(pair.first);
setOfSeconds.insert(pair.second);
}
This list will be very big, and is only necessary for filling the vector and the set (i.e. its content can be invalidated). My question now is, if the following optimization is a good idea:
for (const auto& pair : cachedList)
{
vectorOfFirsts.push_back(std::move(pair.first));
setOfSeconds.insert(std::move(pair.second));
}
Will calling std::move on pair.first somehow invalidate pair.second? And will this code provide any speedup for the loop? I know that it would probably be a good idea to fill the vector/set instead of the list, but the list is filled via some legacy code I have no control over / no time to dig in.
Upvotes: 3
Views: 1451
Reputation: 69892
Stop.
Take a moment to think about this code. Comments inline
// step one - iterate through cachedList, binding the dereferenced
// iterator to a CONST reference
for (const auto& pair : cachedList)
{
// step 2 - use std::move to cast the l-value reference pair to an
// r-value. This will have the type const <pairtype> &&. A const
// r-value reference.
// vector::push_back does not have an overload for const T&& (rightly)
// so const T&& will decay to const T&. You will copy the object.
vectorOfFirsts.push_back(std::move(pair.first));
// ditto
setOfSeconds.insert(std::move(pair.second));
}
It needs to be:
for (auto& pair : cachedList)
{
vectorOfFirsts.push_back(std::move(pair.first));
setOfSeconds.insert(std::move(pair.second));
}
And yes, this then becomes a valid and legitimate use of move.
Upvotes: 3
Reputation: 76307
Will calling std::move on pair.first somehow invalidate pair.second?
No. first
and second
are completely different variables happening to reside in some class object. Moving one does not affect the other.
And will this code provide any speedup for the loop?
It depends on the types. The point of move
-ing something is to transfer resources, basically. Since the pairs here are of int
s and double
s, there are no resources involved, so there is nothing to transfer. Had it been a pair of some matrix type and some tensor type, each with some internal dynamically-allocated buffer, then it might have improved performance.
Upvotes: 6