Title
packaged_task should reject rvalue reference return types
Status
new
Section
[futures.task.general]
Submitter
Casey Carter

Created on 2024-09-28.00:00:00 last changed 2 weeks ago

Messages

Date: 2024-10-03.12:20:03

Proposed resolution:

This wording is relative to N4988.

  1. Modify [futures.task.general] as indicated:

    […]

    -2- When the packaged_task object is invoked, its stored task is invoked and the result (whether normal or exceptional) stored in the shared state. Any futures that share the shared state will then be able to access the stored result.

    namespace std {
      template<class> class packaged_task; // not defined
      
      template<class R, class... ArgTypes>
      class packaged_task<R(ArgTypes...)> {
        […]
      };
      
      template<class R, class... ArgTypes>
      packaged_task(R (*)(ArgTypes...)) -> packaged_task<R(ArgTypes...)>;
      
      template<class F> packaged_task(F) -> packaged_task<see below>;
    }
    

    -?- The program is ill-formed if R is an rvalue reference type.

Date: 2024-09-28.00:00:00

`promise`, `future`, and `shared_future` all refuse rvalue reference types as template arguments (e.g., [futures.promise] paragraphs 1 and 2), but packaged_task<meow&&()> violates no requirements. Its member `get_future` returns future<meow&&>, which is ill-formed, but the other member functions appear to be callable. Nonetheless, at least MSVCSTL, libc++, and libstdc++ all fail to compile simple uses of `packaged_task` with a function type that has an rvalue reference return type (see https://www.godbolt.org/z/5E18nn896).

Presumably the design intent — which the implementers all inferred — is that `packaged_task` should be ill-formed when `get_future` is not instantiable. The spec should say so explicitly rather than relying on the fact that one of the basis operations is unusable.

History
Date User Action Args
2024-10-03 12:20:03adminsetmessages: + msg14414
2024-09-28 00:00:00admincreate