This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.

### 2420. `function<void(ArgTypes...)>` does not discard the return value of the target object

Section: 22.10.17.3 [func.wrap.func] Status: C++17 Submitter: Agustín Bergé Opened: 2014-07-12 Last modified: 2017-07-30

Priority: 1

View all other issues in [func.wrap.func].

View all issues with C++17 status.

Discussion:

`function<void(ArgTypes...)>` should discard the return value of the target object. This behavior was in the original proposal, and it was removed (accidentally?) by the resolution of LWG 870.

Previous resolution [SUPERSEDED]:

> 1. Edit 22.10.17.3 [func.wrap.func] paragraph 2:

>    > A callable object `f` of type `F` is Callable for argument types `ArgTypes` and return type `R` if the expression `INVOKE(f, declval<ArgTypes>()..., R)`, considered as an unevaluated operand (Clause 5), is well formed (22.10.4 [func.require]) and, if `R` is not `void`, implicitly convertible to `R`.

[2014-10-05 Daniel comments]

This side-effect was indeed not intended by 870.

[2015-05, Lenexa]

STL provides improved wording. It replaces the current PR, and intentionally leaves 22.10.17.3 [func.wrap.func] unchanged.

Due to 7 [expr]/6, `static_cast<void>` is correct even when `R` is `const void`.

Proposed resolution:

This wording is relative to N4431.

1. Edit 22.10.4 [func.require] as depicted:

   > -2- Define `INVOKE(f, t1, t2, ..., tN, R)` as `static_cast<void>(INVOKE(f, t1, t2, ..., tN))` if `R` is cv `void`, otherwise `INVOKE(f, t1, t2, ..., tN)` implicitly converted to `R`.

2. Change 22.10.17.3.5 [func.wrap.func.inv] as depicted:

   >     R operator()(ArgTypes... args) const;

   > > -1- Effects Returns: `INVOKE(f, std::forward<ArgTypes>(args)..., R)` (20.9.2), where `f` is the target object (20.9.1) of `*this`.

   > > -2- Returns: Nothing if `R` is `void`, otherwise the return value of `INVOKE(f, std::forward<ArgTypes>(args)..., R)`.