Использование std::move на pair.first делает недействительным pair.second?

У меня есть следующий код в моем проекте на данный момент:

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);
}

Этот список будет очень большим и необходим только для заполнения вектора и набора (т. Е. Его содержимое может быть признано недействительным). Мой вопрос сейчас, если следующая оптимизация является хорошей идеей:

 for (const auto& pair : cachedList)
 {
       vectorOfFirsts.push_back(std::move(pair.first));
       setOfSeconds.insert(std::move(pair.second));
 }

Будет ли вызов std::move на pair.first каким-то образом лишать законной силы pair.second? И будет ли этот код обеспечивать ускорение цикла? Я знаю, что, вероятно, было бы неплохо заполнить вектор / набор вместо списка, но список заполняется с помощью какого-то унаследованного кода, над которым у меня нет контроля / нет времени копаться.

2 ответа

Решение

Будет ли вызов std::move на pair.first каким-то образом лишать законной силы pair.second?

Нет. first а также second совершенно разные переменные, происходящие в некотором объекте класса. Перемещение одного не влияет на другое.

И будет ли этот код обеспечивать ускорение цикла?

Это зависит от типов. Точка moveЧто-то значит переводить ресурсы, в основном. Поскольку пары здесь intс и doubles, ресурсы не задействованы, поэтому передавать нечего. Если бы это была пара некоторого матричного типа и некоторого тензорного типа, каждый с некоторым внутренним динамически распределенным буфером, то это могло бы улучшить производительность.

Стоп.

Найдите минутку, чтобы подумать об этом коде. Встроенные комментарии

// 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));
 }

Это должно быть:

for (auto& pair : cachedList)
{
  vectorOfFirsts.push_back(std::move(pair.first));
  setOfSeconds.insert(std::move(pair.second));
}

И да, это тогда становится действительным и законным использованием движения.

Другие вопросы по тегам