std::ignore(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… std::ignore β€” the C++ Standard Library's most unbothered icon

okay so this is from the C++ Standard Library, and honestly bestie, std::ignore is the literal embodiment of "not my problem" energy. It lives over on cppreference and it's giving main character of "I simply will not be perceiving that." Let's get into it ✨


πŸ“› NAME

std::ignore β€” yes. that's it. that's the name. std::ignore πŸŽ€ (the manpage header is literally just std::ignore twice, and honestly? iconic.)


✨ Synopsis

First things first, where does it live:

Defined in header <tuple>

And here's the actual declaration, in all its two-version glory:

const /*unspecified*/ ignore;             (since C++11)
                                          (until C++17)
inline constexpr /*unspecified*/ ignore;  (since C++17)

So what is it? It's an object of unspecified type β€” the type is a mystery, the type is a vibe, we don't know her β€” such that any value can be assigned to it with no effect. Like, you can assign literally anything and nothing happens. Zero consequences. No cap. 🫢

It's intended for use with std::tie when you're unpacking a std::tuple, as a placeholder for the arguments that you're not using. You know when you get back a tuple and you only care about some of it? Yeah. That's the moment. Drop an std::ignore in the slots you don't care about and move on with your life πŸ’…

⚠️ Okay so important caveat time: while the behavior of std::ignore outside of std::tie is not formally specified, some code guides recommend using std::ignore to avoid warnings from unused return values of [[nodiscard]] functions. So like. people do it. the guides say it's fine. but "not formally specified" is doing a lot of heavy lifting there, so just know that going in πŸ™ˆ

🧚 Possible implementation

Here's how you could lowkey implement it yourself, the whole detail namespace slay:

namespace detail {
struct ignore_t
{
    template <typename T>
    constexpr // required since C++14
    void operator=(T&&) const noexcept {}
};
}
inline constexpr detail::ignore_t ignore; // 'const' only until C++17

Look at that operator=. It takes a forwarding reference, returns void, and the body is {}. An empty body. She does nothing. She is perfect. 😭 The constexpr is required since C++14 btw β€” don't forget it! And that trailing comment is important: // 'const' only until C++17. ✨


🌸 Example

The example does two whole things, and here they are:

  1. Demonstrates the use of std::ignore together with a [[nodiscard]] function.
  2. Unpacks a std::pair<iterator, bool> returned by std::set::insert(), but only saves the boolean.
// Run this code

#include <iostream>
#include <set>
#include <string>
#include <tuple>

[[nodiscard]] int dontIgnoreMe()
{
    return 42;
}

int main()
{
    std::ignore = dontIgnoreMe();

    std::set<std::string> set_of_str;
    bool inserted = false;
    std::tie(std::ignore, inserted) = set_of_str.insert("Test");
    if (inserted)
        std::cout << "Value was inserted successfully\n";
}

The way that dontIgnoreMe() is literally named dontIgnoreMe and we ignore it anyway 😭 the disrespect. the audacity. we love to see it. And then std::tie(std::ignore, inserted) snags just the bool out of the pair and lets the iterator go β€” the std::ignore is the placeholder doing the emotional labor. πŸ”₯

Output

Value was inserted successfully

periodt. it worked. πŸ’–


πŸ‘‘ See also

  • tie β€” creates a tuple of lvalue references or unpacks a tuple into individual objects (since C++11). It's a function template. She's the one who actually makes the unpacking happen, so go say hi. πŸ¦‹

okay that's the whole page bestie, no notes, go ignore some return values responsibly (but remember: outside of std::tie, it's not formally specified, k? πŸ’€)

that was std::ignore, from the C++ Standard Library, brought to you by cppreference.com, version 2024.06.10 β€” til next time, mwah πŸŽ€πŸ’œβœ¨

πŸ“¦ where this page comes from