Let\'s imagine you need to call the following method:
std::tuple foo();
In C++17, you can call the function and unpack
MSVC has already fixed this in VS 15.7 Preview. The final 15.7 release should be available in the coming weeks. This means that the current logic supported by the latest releases of all major compilers is as follows:
If none of the bindings in a structured binding declaration are used, it is possible to silence the warning by using the [[maybe_unused]]
attribute:
[[maybe_unused]] auto [a, b, c] = foo();
Unfortunately structured bindings do not explicitly support discarding members, and attributes such as [[maybe_unused]] cannot be applied to structured bindings (there's a proposal for that: P0609: "Attributes for Structured Bindings").
Here's a possible solution:
auto [a, b, c] = foo();
(void) a; // unused
Another alternative is to use an std::tie
:
int b, c;
std::tie(std::ignore, b, c) = foo();
Edit
As mentioned in the comments, there are some issues with this approach:
You could write a helper function that only gives you back certain indices of a std::tuple
:
template <size_t... Is, typename Tuple>
auto take_only(Tuple&& tuple) {
using T = std::remove_reference_t<Tuple>;
return std::tuple<std::tuple_element_t<Is, T>...>(
std::get<Is>(std::forward<Tuple>(tuple))...);
}
auto [b, c] = take_only<1, 2>(foo());
Or drops the head or something:
template <size_t... Is, typename Tuple>
auto drop_head_impl(Tuple&& tuple, std::index_sequence<0, Is...> ) {
return take_only<Is...>(std::forward<Tuple>(tuple));
}
template <typename Tuple>
auto drop_head(Tuple&& tuple) {
return drop_head_impl(std::forward<Tuple>(tuple),
std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>());
}
auto [b, c] = drop_head(foo());
But the above implementations almost certainly have some lifetime complexity issues that directly using structured bindings won't - since there isn't any lifetime extension here.
So just, do what Vittorio says:
auto [a, b, c] = foo();
(void)a;