PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Saturday, November 5, 2022

[FIXED] How to transform 2D tuple [x][y] to [y][x] and call variadic function for each result set

 November 05, 2022     c++, c++20, lambda, tuples, variadic-functions     No comments   

Issue

I want to "rotate" the axis of a 2D tuple and call a variadic function for each of the result sets.

All tuple elements have the same type, but the element items/attributes might have different type.

Starting from

constexpr auto someData = std::make_tuple(
    std::make_tuple(1, 2, 3.0),
    std::make_tuple(4, 5, 6.0),
    std::make_tuple(7, 8, 9.0));

the result I want to achieve, are calls to a variadic function like this

 someFunction(1, 4, 7);
 someFunction(2, 5, 8);
 someFunction(3.0, 6.0, 9.0);

I was trying to solve this using std::get<index>(tuple) in a lambda to create indices using std::make_index_sequence and invoke a variadic function, passing tuple elements via std::apply, like this (without success).

#include <iostream>
#include <tuple>
constexpr auto someFunction(auto&&... args) {
    //do some stuff
    ((std::cout << args),...);
}
int main() {
    constexpr auto someData = std::make_tuple(
        std::make_tuple(1, 2, 3.0),
        std::make_tuple(4, 5, 6.0),
        std::make_tuple(7, 8, 9.0)
    );

    // want to get
    // someFunction(1, 4, 7);
    // someFunction(2, 5, 8);
    // someFunction(3.0, 6.0, 9.0);

    using t0_t = typename std::tuple_element<0, decltype(someData)>::type;
    [] <std::size_t... I> (auto&& tuple, std::index_sequence<I...>) {
        ([&] (std::size_t i) {
            std::apply([&](auto&&... args) {
                //(std::get<i>(args), ...);
                // someFunction ((std::get<i>(args), ...));
            }, tuple);
        }(I), ...);
    }(std::forward<decltype(someData)>(someData),
        std::make_index_sequence<std::tuple_size<t0_t>::value>{});
}

How can that be done correctly?


Solution

Use nested lambdas, one to expand the index and one to expand the tuple

constexpr auto someData = std::make_tuple(
  std::make_tuple(1, 2, 3.0),
  std::make_tuple(4, 5, 6.0),
  std::make_tuple(7, 8, 9.0)
);

// someFunction(1, 4, 7);
// someFunction(2, 5, 8);
// someFunction(3.0, 6.0, 9.0);

std::apply([](auto first_tuple, auto... rest_tuples) {
  [&]<std::size_t... I>(std::index_sequence<I...>) {
    ([]<size_t N>(auto... tuples) {
      someFunction(std::get<N>(tuples)...);
    }.template operator()<I>(first_tuple, rest_tuples...), ...);
  }(std::make_index_sequence<std::tuple_size_v<decltype(first_tuple)>>{});
}, someData);

Demo



Answered By - 康桓瑋
Answer Checked By - Marilyn (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing