I know that you can use static_cast<void>
, but it just seems too verbose for me, and not reflecting the original intent that I want to discard a return value, not to cast it to anything.
Recently I stumbled upon std::ignore
, which can accept a value of any type, the name is clear and readable, and to me it seems fitting.
I know that the initial intent was to use std::ignore
alongside with std::tie
to discard any unwanted values, but I guess the original intent of static_cast
was to actually cast values for some better reasons than discarding values so the compiler won't complain.
So, is it OK to use std::ignore
for the purpose I described in the question?
For example:
std::ignore = std::transform(...);
Using std::ignore
outside of std::tie
is supported since C++26 (see P2968: Make std::ignore a first-class object).
Even before it was officially supported, it was 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, usestd::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 used to be 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 int
isignore
, assigning any value to the corresponding tuple element has no effect.
This is mostly a philosophical issue though. In every major standard library, std::ignore
has been implemented in such a way that you can do std::ignore = ...
on its own.
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.