Yes, it is okay. In fact, it is considered much better style by some people.
Never cast to (void)
to ignore a [[nodiscard]]
return value. If you deliberately want to discard such a result, first think hard about whether that is really a good idea (there is usually a good reason the author of the function or of the return type used [[nodiscard]]
in the first place). If you still think it’s appropriate and your code reviewer agrees, use std::ignore =
to turn off the warning which is simple, portable, and easy to grep.
- CppCoreGuidelines ES.48: Avoid casts
Note: Herb Sutter committed the guideline. With the std::ignore
rule, you can consistently teach not to use casts, and don't have to make an exception for casting to void
.
An argument against std::ignore
is that it is only defined in terms of its effect in std::tie
:
template<class... TTypes>
constexpr tuple<TTypes&...> tie(TTypes&... t) noexcept;
Returns: tuple<TTypes&...>(t...)
. When an argument in t
is ignore
, assigning any value to the corresponding tuple element has no effect.
- [utilities] std::tie
This is mostly a philosophical issue though. In every major standard library, std::ignore
is implemented in such a way that you can do std::ignore = ...
on its own, and this may soon be well-defined. See P2968: Make std::ignore
a first-class object.
In the end, it's stylistic preference. You can use (void)
, static_cast<void>
, or std::ignore
. They are all acceptable, and which one to use is a matter of opinion.
What matters is that you use a consistent style throughout your project, i.e. if you use std::ignore
to discard results in one place, use it everywhere.
std::ignore
is only defined in terms of its use instd::tie
. Strictly speaking, I think it would have to bestd::tie(std::ignore) = std::tie(std::transform(...));
. – Coexecutorstd::tie
(std::ignore = dontIgnoreMe();
). – Fideismignore
here and (besides the stream function) it only appears as part of tuple creation. – Coexecutorstatic_cast<void>
, this is one case where it is generally harmless to use an explicit conversion tovoid
like(void)my_function();
. Nobody can use the result, by definition, which eliminates most of the risks related to using them. And it is a relatively well known convention, so shouldn't act as a red flag or cause for confusion or concern. – Coexecutorstd::transform
doesn't return a[[nodiscard]]
. sostd::ignore =
can even be removed :-), no warnings expected (else we would prefix any expression by it asstd::ignore = std::cout << "hello"
:) ). – Disconnect// my_lint_tool_ignore_flag
might be an alternative too. (or maybe the warning is more subtle that just ignoring the return value). – Disconnectstd::transform
isn't a no-discard, in fact it alters something passed to it. And, unless some mistakes were made,[[nodiscard]]
functions are pure, i.e. they have no side effect and do not alter their arguments, so they are literally a no-op o.o – Triptych(void)
. Everyone understands what that's doing and it's very idiomatic at this point. – Crustaceous