This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
function<void()> suppresses nodiscard warningsSection: 22.10.4 [func.require] Status: New Submitter: Jonathan Wakely Opened: 2025-05-29 Last modified: 2025-10-21
Priority: 3
View other active issues in [func.require].
View all other issues in [func.require].
View all issues with New status.
Discussion:
struct [[nodiscard]] A { };
A f();
std::function<void()> func = f;
Invoking func() will discard the return value of f(), but there will be
no warning. This is because INVOKE<void>(...)
is defined in terms of static_cast<void>(...) and the
explicit cast to void suppresses nodiscard warnings.
This is in contast to INVOKE<R>(...) where the
conversion to non-void R is implicit.
It seems right that std::invoke_r<void>(f) should not give
nodiscard warnings, because that's quite explicit about converting to void,
and similarly for std::bind<void>(f)().
However, I think it's debatable whether all uses of INVOKE<void> (and std::function<void()> in particular)
intend an explicit cast to void that ignores nodiscard types.
It's very easy to set f as the target of func and then lose its warning,
and there's no explicit use of void when you write func = f; func();.
We could consider defining INVOKE<void>(...) to be
an expression of type void, without explicitly saying there's a cast to void.
For example, (INVOKE(...), void()) would invoke the invocable and have type
void, but would not require any nodiscard warnings to be suppressed.
If we did that, some uses of INVOKE<R> such as
std::invoke_r and std::bind<R> might need to
be adjusted to preserve the explicit conversion to void.
That would allow us to be selective about which uses of
INVOKE<void> we consider to be explicit about
discarding results, and which we don't.
[2025-10-21; Reflector poll.]
Set priority to 3 after reflector poll.
Split opinions between considering this NAD due warnings being QoI matter,
and explicit use static_cast<void> indicating that any
nodiscard warning should be silenced.
Concerns where expressed that removing static_assert is insufficient,
as warnings may be still suppressed by heuristics that remove warnings
originating from system headers.
Proposed resolution: