Stefan
Stefan

Reputation: 226

Does using std::move on pair.first invalidate pair.second?

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

Answers (2)

Richard Hodges
Richard Hodges

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

Ami Tavory
Ami Tavory

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 ints and doubles, 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

Related Questions