std::ignore with structured bindings?

C++C++17Language LawyerStructured BindingsStd Tie

C++ Problem Overview


Prelude:

std::tuple<int, int, int> f();
std::tuple<int, int, float, int> g();

C++1z will introduce syntax for structured bindings which will make it possible to write instead of

int a, b, c;
std::tie(a, b, c) = f();

something like

auto [a, b, c] = f();

However, std::tie also allowed to specify std::ignore to ignore certain components, e.g:

std::tie(a, b, std::ignore, c) = g();

Will it be possible to do something similar using the new structured bindings syntax? How would it work?

C++ Solutions


Solution 1 - C++

The structured bindings proposal contains a dedicated section answering your question (P0144R2):

> 3.8 Should there be a way to explicitly ignore components?

> The motivation would be to silence compiler warnings about unused names. We think the answer should be “not yet.” This is not motivated by use cases (silencing compiler warnings is a motivation, but it is not a use case per se), and is best left until we can revisit this in the context of a more general pattern matching proposal where this should fall out as a special case.

> Symmetry with std::tie would suggest using something like a std::ignore:

> tuple f();

> auto [x, std::ignore, z] = f(); // NOT proposed: ignore second element

> However, this feels awkward.

> Anticipating pattern matching in the language could suggest a wildcard like _ or *, but since we do not yet have pattern matching it is premature to pick a syntax that we know will be compatible. This is a pure extension that can wait to be considered with pattern matching.

However, note that the working draft of the Standard is currently being revised by the relevant National Bodies (NB), and there is a NB comment requesting this feature (P0488R0, US100):

> Decomposition declarations should provide syntax to discard some of the returned values, just as std::tie uses std::ignore.

Solution 2 - C++

> Will it be possible to do something similar using the new structured bindings syntax?

No. You'll just have to make up a variable name that won't be mentioned later.

Solution 3 - C++

I usually use _ which is a valid identifier in C++ but looks the same as for example Kotlin's underscore operator which discards lambda parameters. You'd end up with a nice code sth like this

map([&](auto it) {
    auto [_, deviceServiceXAddr] = it;
    return deviceServiceXAddr;
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjotikView Question on Stackoverflow
Solution 1 - C++metalfoxView Answer on Stackoverflow
Solution 2 - C++Nicol BolasView Answer on Stackoverflow
Solution 3 - C++fooView Answer on Stackoverflow