Лучший способ создать std :: future <T>из T - PullRequest
2 голосов
/ 13 января 2020

Я использую std::future<T> для хранения результата необязательной асинхронной операции. В зависимости от аргументов функции операция может быть асинхронной или синхронной. В синхронном случае у меня есть значение, которое я хочу сохранить в future. Как мне лучше всего это сделать?

Примеры, приведенные в https://en.cppreference.com/w/cpp/thread/future:

  1. future от packaged_task
  2. future из async()
  3. future из promise

Но нет make_future, и конструктор future не позволяет создавать выполняется future из значения. Поэтому я создал вспомогательную функцию для этого, пройдя через promise следующим образом:

template <typename T>
std::future<T> make_future(T&& t)
{
   std::promise<T> p;
   p.set_value(std::forward<T>(t));
   return p.get_future();
}

Это правильный способ создания std::future<T> из T?

Есть ли лучший способ создать std::future<T> из T?

EDIT: пример, кэш:

Foo readAndCacheFoo(int id);

std::future<Foo> readFooAsync(int id)
{
   {
      const lock_guard lock{cacheMutex};
      if (id == cachedId)
      {
         return make_future(cachedFoo);
      }
   }

   return std::async(readAndCacheFoo, id);
}

Ответы [ 2 ]

0 голосов
/ 13 января 2020

Это правильный способ создания std :: future из T?

Да, это так.

Однако я бы сказал, что make_future Возможно, это не самое подходящее имя. Вся идея класса 'future' заключается в том, что его значение может быть готово в будущем, а ваша функция всегда возвращает уже выполненное будущее.

Ну, это просто имя ... Afaik, ваша логика c прекрасно.

0 голосов
/ 13 января 2020

Это можно сделать довольно легко, но это немного запутанно:

template <typename T>
std::future<T> make_future(T&& t)
{
    auto fun = [val=std::forward<T>(t)]() { return val; };
    std::packaged_task<T()> task(std::move(fun));
    auto future = task.get_future();
    task();
    return future;
}

Обратите внимание, что std::future и packaged_task должны иметь общее внутреннее состояние, поэтому это должно быть безопасно

РЕДАКТИРОВАТЬ: на самом деле кажется, что ваш код действителен и даже проще

...