Как заставить метод принимать вектор <string>&& вместо вектора <string>? - PullRequest
0 голосов
/ 05 апреля 2019

Я хочу не брать копии векторов и использовать вместо них ссылки на rvalue. Это методы.

    bool GeckoChildProcessHost::SyncLaunch(std::vector<std::string> 
aExtraOpts, int aTimeoutMs) {
  if (!AsyncLaunch(std::move(aExtraOpts))) {
    return false;
  }
  return WaitUntilConnected(aTimeoutMs);
}

bool GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts) 
{
  PrepareLaunch();

#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
  if (IsMacSandboxLaunchEnabled()) {
    AppendMacSandboxParams(aExtraOpts);
  }
#endif

  MessageLoop* ioLoop = XRE_GetIOMessageLoop();

  MOZ_ASSERT(mHandlePromise == nullptr);
  mHandlePromise = new HandlePromise::Private(__func__);

  // Currently this can't fail (see the MOZ_ALWAYS_SUCCEEDS in
  // MessageLoop::PostTask_Helper), but in the future it possibly
  // could, in which case this method could return false.
  ioLoop->PostTask(NewNonOwningRunnableMethod<std::vector<std::string>>(
      "ipc::GeckoChildProcessHost::RunPerformAsyncLaunch", this,
      &GeckoChildProcessHost::RunPerformAsyncLaunch, aExtraOpts));

  return true;
}

Как мне это сделать? Также я считаю, что мне нужно будет поменять своих абонентов, чтобы использовать move. Как бы я это сделал? Вот код одного из абонентов.

 bool GeckoChildProcessHost::LaunchAndWaitForProcessHandle( StringVector 
aExtraOpts) {
  if (!AsyncLaunch(std::move(aExtraOpts))) {
    return false;
  }

  MonitorAutoLock lock(mMonitor);
  while (mProcessState < PROCESS_CREATED) {
    lock.Wait();
  }
  MOZ_ASSERT(mProcessState == PROCESS_ERROR || mChildProcessHandle);

  return mProcessState < PROCESS_ERROR;
}

Любая помощь приветствуется. Спасибо!

1 Ответ

0 голосов
/ 05 апреля 2019

Но нигде не используется вектор &&.Это в основном то, что я хочу сделать.

Вы уверены, что хотите это сделать?Вот что вы написали прямо перед этим:

Я хочу не брать копии вектора

Так что, если я правильно понимаю, вы хотите переместить вектор вместо его копирования.

Дело в том, что вы делаете все правильно прямо сейчас.Вы не должны использовать ссылку rvalue для перемещения данных.Фактически, использование ссылки на rvalue для вашего параметра функции предотвратит перемещение (оно будет проходить по ссылке, а не по перемещению).Ссылка Rvalue используется для реализации семантики перемещения.Что вам действительно нужно для перемещения переменной, так это использовать std::move при передаче ее по значению, вызывая перемещение, которое вы уже делаете.

Видите, конструктор перемещения и копирования находится в том же наборе перегрузки.Существует оптимизированная версия «copy», которая может быть вызвана при отправке ему значения.Иногда вы все еще хотите, чтобы компилятор выбрал оптимизированную версию, потому что вам все равно, что случится с вашей переменной.Функция std::move делает это.Просто конвертируйте lvalue в rvalue.Затем конструктор перемещения выполняет фактическое перемещение.

В своем коде вы делаете это:

// no copy, even if AsyncLaunch is taking by
// value, since we 'move' into the value
!AsyncLaunch(std::move(aExtraOpts)) 

Вы приводите aExtraOpts в rvalue, который перемещает данные в параметр value,Если бы функция принимала аргумент по ссылке (или по ссылке rvalue), тогда вообще не было бы никакого перемещения, просто ссылки.

...