Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate over tuple elements with std::apply

I wanted to archieve a way of applying a function to each element of a given tuple and I came up with a solution that is demonstrated in the following example.

int main()
{
    std::apply([](auto&&... xs)
               { 
                   [](...){}(([](auto&& x){ std::cout << x << "\n"; }(std::forward<decltype(xs)>(xs)), false)...); 
               }, std::make_tuple(1, 2.f, 3.0));
}

This seems to work fine except that the tuple elements seem to be processed in an inverted order, leading to the following output:

3
2
1

Can anyone tell me why?

like image 273
Yamahari Avatar asked Apr 21 '17 11:04

Yamahari


People also ask

Can we access elements of tuple through iteration?

To iterate over items of a Tuple in Python, use for loop. During each iteration, we get access to an element from Tuple corresponding to that iteration.


1 Answers

The order in which the arguments to your inner, empty lambda [](...){} are evaluated is unspecified (even after the paper on evaluation order).

Just use a fold on the comma operator:

std::apply([](auto&&... xs) {
               ((std::cout << std::forward<decltype(xs)>(xs) << '\n'), ...); },
           std::make_tuple(1, 2.f, 3.0));

Demo. Or binary-fold over cout directly. Once we introduce an "packize" operator, for which there's a proposal out already (using [:]), you could also write (std::cout << [:]tup << '\n'), ....

like image 157
Columbo Avatar answered Sep 19 '22 10:09

Columbo