33 Thread support library [thread]

33.6 Futures [futures]

33.6.10 Class template packaged_­task [futures.task]

Шаблон классаpackaged_­task определяет тип оболочки для функции или вызываемого объекта, чтобы возвращаемое значение функции или вызываемого объекта сохранялось в будущем при его вызове.

Когдаpackaged_­task объект вызывается, вызывается его сохраненная задача, а результат (нормальный или исключительный) сохраняется в общем состоянии. Любые фьючерсы, которые разделяют общее состояние, затем смогут получить доступ к сохраненному результату.

namespace std {
  template<class> class packaged_task; // not defined

  template<class R, class... ArgTypes>
  class packaged_task<R(ArgTypes...)> {
  public:
    // construction and destruction
    packaged_task() noexcept;
    template <class F>
      explicit packaged_task(F&& f);
    ~packaged_task();

    // no copy
    packaged_task(const packaged_task&) = delete;
    packaged_task& operator=(const packaged_task&) = delete;

    // move support
    packaged_task(packaged_task&& rhs) noexcept;
    packaged_task& operator=(packaged_task&& rhs) noexcept;
    void swap(packaged_task& other) noexcept;

    bool valid() const noexcept;

    // result retrieval
    future<R> get_future();

    // execution
    void operator()(ArgTypes... );
    void make_ready_at_thread_exit(ArgTypes...);

    void reset();
  };
  template <class R, class... ArgTypes>
    void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
  template <class R, class Alloc>
    struct uses_allocator<packaged_task<R>, Alloc>;
}

33.6.10.1 packaged_­task member functions [futures.task.members]

packaged_task() noexcept;

Effects: Создаетpackaged_­task объект без общего состояния и без сохраненной задачи.

template <class F> packaged_task(F&& f);

Requires: INVOKE<R>(f, t1, t2, ..., tN), гдеt1, t2, ..., tN - значения соответствующих типов вArgTypes..., должно быть допустимым выражением. Вызов копииf должен вести себя так же, как и вызовf.

Remarks: Этот конструктор не должен участвовать в разрешении перегрузки, еслиdecay_­t<F> он того же типа, что иpackaged_­task<R(ArgTypes...)>.

Effects: Создает новыйpackaged_­task объект с общим состоянием и инициализирует сохраненную задачу объекта с помощьюstd​::​forward<F>(f).

Throws:

  • Любые исключения, создаваемые конструктором копирования или перемещенияf.

  • Для первой версии, bad_­alloc если не удалось выделить память для внутренних структур данных.

  • Для второй версии любые исключения, созданныеallocator_­traits<Allocator>​::​template rebind_­traits<unspecified>​::​allocate.

packaged_task(packaged_task&& rhs) noexcept;

Effects: Создает новыйpackaged_­task объект и передает владение rhsобщим состоянием*this, оставив егоrhs без общего состояния. Перемещает сохраненную задачу изrhs в*this.

Postconditions:rhs не имеет общего состояния.

packaged_task& operator=(packaged_task&& rhs) noexcept;

Effects:

  • Освобождает любое разделяемое состояние ([futures.state]);

  • звонкиpackaged_­task(std​::​move(rhs)).swap(*this).

~packaged_task();

Effects: Отменяет любое общее состояние ([futures.state]).

void swap(packaged_task& other) noexcept;

Effects: Меняет общие состояния и сохраненные задачи*this иother.

Postconditions:*this имеет такое же общее состояние и сохраненную задачу (если есть), что иother до вызоваswap.other имеет такое же общее состояние и сохраненную задачу (если есть), что и*this до вызоваswap.

bool valid() const noexcept;

Returns:true только если*this есть общее состояние.

future<R> get_future();

Returns: future Объект , который разделяет то же общегосударственный как*this.

Throws: future_­error объекта в случае возникновения ошибки.

Error conditions:

  • future_­already_­retrieved ifget_­future уже был вызван дляpackaged_­task объекта с тем же общим состоянием, что и*this.

  • no_­state если*this не имеет общего состояния.

void operator()(ArgTypes... args);

Effects: Как будто поINVOKE<R>(f, t1, t2, ..., tN), гдеf хранится задача*this и t1, t2, ..., tN значения вargs.... Если задача возвращается нормально, возвращаемое значение сохраняется как асинхронный результат в общем состоянии *this, в противном случае сохраняется исключение, созданное задачей. Общее состояние*this готово, и все потоки, заблокированные в функции, ожидающие*this готовности общего состояния , разблокируются.

Throws: future_­error объект исключения , если нет общегосударственных или сохраненное задание уже вызван.

Error conditions:

  • promise_­already_­satisfied если сохраненная задача уже была вызвана.

  • no_­state если*this не имеет общего состояния.

void make_ready_at_thread_exit(ArgTypes... args);

Effects: Как будто поINVOKE<R>(f, t1, t2, ..., tN), гдеf хранится задача, а t1, t2, ..., tN какие - значения вargs.... Если задача возвращается нормально, возвращаемое значение сохраняется как асинхронный результат в общем состоянии *this, в противном случае сохраняется исключение, созданное задачей. В любом случае это должно быть сделано без[futures.state]немедленного преобразования этого состояния в состояние ready ( ). Планирует подготовить общее состояние к моменту выхода из текущего потока после того, как все объекты продолжительности хранения потока, связанные с текущим потоком, будут уничтожены.

Throws:future_­error если возникает состояние ошибки.

Error conditions:

  • promise_­already_­satisfied если сохраненная задача уже была вызвана.

  • no_­state если*this не имеет общего состояния.

void reset();

Effects: Как будто*this = packaged_­task(std​::​move(f)), где f хранится задача *this. [ Note: Это создает новое общее состояние для*this. Старое состояние заброшено ([futures.state]). ]end note

Throws:

  • bad_­alloc если не удалось выделить память для нового общего состояния.

  • любое исключение, созданное конструктором перемещения задачи, хранящейся в общем состоянии.

  • future_­error с ошибкойno_­state if*this не имеет общего состояния.

33.6.10.2 packaged_­task globals [futures.task.nonmembers]

template <class R, class... ArgTypes> void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;

Effects: Как будто мимоx.swap(y).

template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc> : true_type { };

Requires:Alloc должен бытьAllocator.