Files
2025-10-25 03:02:53 +03:00

12 KiB
Raw Permalink Blame History

[futures.shared.future]

32 Concurrency support library [thread]

32.10 Futures [futures]

32.10.8 Class template shared_future [futures.shared.future]

1

#

The class template shared_future defines a type for asynchronous return objects which may share their shared state with other asynchronous return objects.

A default-constructed shared_future object has no shared state.

A shared_future object with shared state can be created by conversion from a future object and shares its shared state with the original asynchronous provider of the shared state.

The result (value or exception) of a shared_future object can be set by calling a respective function on an object that shares the same shared state.

2

#

[Note 1:

Member functions of shared_future do not synchronize with themselves, but they synchronize with the shared state.

— end note]

3

#

The effect of calling any member function other than the destructor, the move assignment operator, the copy assignment operator, orvalid() on a shared_future object for which valid() == false is undefined.

[Note 2:

It is valid to copy or move from a shared_future object for which valid() is false.

— end note]

Recommended practice: Implementations should detect this case and throw an object of typefuture_error with an error condition of future_errc::no_state.

🔗

namespace std {templateclass shared_future {public: shared_future() noexcept; shared_future(const shared_future& rhs) noexcept; shared_future(future&&) noexcept; shared_future(shared_future&& rhs) noexcept; ~shared_future(); shared_future& operator=(const shared_future& rhs) noexcept; shared_future& operator=(shared_future&& rhs) noexcept; // retrieving the valuesee below get() const; // functions to check statebool valid() const noexcept; void wait() const; template<class Rep, class Period> future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const; template<class Clock, class Duration> future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; };}

4

#

For the primary template, R shall be an object type that meets the Cpp17Destructible requirements.

5

#

The implementation provides the template shared_future and two specializations, shared_future<R&> and shared_future.

These differ only in the return type and return value of the member function get, as set out in its description, below.

🔗

shared_future() noexcept;

6

#

Effects: The object does not refer to a shared state.

7

#

Postconditions: valid() == false.

🔗

shared_future(const shared_future& rhs) noexcept;

8

#

Effects: The object refers to the same shared state as rhs (if any).

9

#

Postconditions: valid() returns the same value as rhs.valid().

🔗

shared_future(future<R>&& rhs) noexcept; shared_future(shared_future&& rhs) noexcept;

10

#

Effects: Move constructs a shared_future object that refers to the shared state that was originally referred to by rhs (if any).

11

#

Postconditions:

  • (11.1)

    valid() returns the same value as rhs.valid() returned prior to the constructor invocation.

  • (11.2)

    rhs.valid() == false.

🔗

~shared_future();

12

#

Effects:

Releases any shared state ([futures.state]);

destroys *this.

🔗

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

13

#

Effects: If addressof(rhs) == this is true, there are no effects.

Otherwise:

Releases any shared state ([futures.state]);

move assigns the contents of rhs to *this.

14

#

Postconditions:

  • (14.1)

    valid() returns the same value as rhs.valid() returned prior to the assignment.

  • (14.2)

    If addressof(rhs) == this is false,rhs.valid() == false.

🔗

shared_future& operator=(const shared_future& rhs) noexcept;

15

#

Effects: If addressof(rhs) == this is true, there are no effects.

Otherwise:

Releases any shared state ([futures.state]);

assigns the contents of rhs to *this. [Note 3: As a result,*this refers to the same shared state as rhs (if any). — end note]

16

#

Postconditions: valid() == rhs.valid().

🔗

const R& shared_future::get() const; R& shared_future<R&>::get() const; void shared_future<void>::get() const;

17

#

[Note 4:

As described above, the template and its two required specializations differ only in the return type and return value of the member function get.

— end note]

18

#

[Note 5:

Access to a value object stored in the shared state is unsynchronized, so operations on R might introduce a data race ([intro.multithread]).

— end note]

19

#

Effects: wait()s until the shared state is ready, then retrieves the value stored in the shared state.

20

#

Returns:

  • (20.1)

    shared_future::get() returns a const reference to the value stored in the object's shared state. [Note 6: Access through that reference after the shared state has been destroyed produces undefined behavior; this can be avoided by not storing the reference in any storage with a greater lifetime than the shared_future object that returned the reference. — end note]

  • (20.2)

    shared_future<R&>::get() returns the reference stored as value in the object's shared state.

  • (20.3)

    shared_future::get() returns nothing.

21

#

Throws: The stored exception, if an exception was stored in the shared state.

🔗

bool valid() const noexcept;

22

#

Returns: true only if *this refers to a shared state.

🔗

void wait() const;

23

#

Effects: Blocks until the shared state is ready.

🔗

template<class Rep, class Period> future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;

24

#

Effects: None if the shared state contains a deferred function ([futures.async]), otherwise blocks until the shared state is ready or until the relative timeout ([thread.req.timing]) specified byrel_time has expired.

25

#

Returns:

  • (25.1)

    future_status::deferred if the shared state contains a deferred function.

  • (25.2)

    future_status::ready if the shared state is ready.

  • (25.3)

    future_status::timeout if the function is returning because the relative timeout ([thread.req.timing]) specified by rel_time has expired.

26

#

Throws: timeout-related exceptions ([thread.req.timing]).

🔗

template<class Clock, class Duration> future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

27

#

Effects: None if the shared state contains a deferred function ([futures.async]), otherwise blocks until the shared state is ready or until the absolute timeout ([thread.req.timing]) specified byabs_time has expired.

28

#

Returns:

  • (28.1)

    future_status::deferred if the shared state contains a deferred function.

  • (28.2)

    future_status::ready if the shared state is ready.

  • (28.3)

    future_status::timeout if the function is returning because the absolute timeout ([thread.req.timing]) specified by abs_time has expired.

29

#

Throws: timeout-related exceptions ([thread.req.timing]).