Home > Back-end >  Printing Pairs inside tuple in C
Printing Pairs inside tuple in C

Time:01-30

I am trying to print all the values of pair inside of a tuple,

header file

template <typename... Args>
void printPairs(std::tuple<Args...> t)
{
    for (int i = 0; i <= 4; i  )  //the value of 'i' is not usable in a constant expression
    {
        auto pair = std::get<i>(t);
        cout << pair.first << " " << pair.second << endl;
    }
}

Main.cpp

std::tuple<std::pair<int, int>, std::pair<int, int>, std::pair<int, int>, std::pair<int, int>> t1 = {std::make_pair(1, 2), std::make_pair(3, 4), std::make_pair(5, 6), std::make_pair(7, 8)};
printPairs(t1);

If you would not iterate and put a constant value instead of "i", works fine

auto pair = std::get<1>(t);
 cout << pair.first << " " << pair.second << endl;

CodePudding user response:

You can use std::apply:

template<typename Tuple>
void printPairs(const Tuple& t) {
  std::apply([](const auto&... pair) {
    ((std::cout << pair.first << " " << pair.second << std::endl), ...);
  }, t);
}

CodePudding user response:

Something along these lines, perhaps:

template <typename... Args, size_t... Is>
void printPairsHelper(const std::tuple<Args...>& t, std::index_sequence<Is...>) {
    ((std::cout << std::get<Is>(t).first << " "
                << std::get<Is>(t).second << std::endl), ...);
}

template <typename... Args>
void printPairs(const std::tuple<Args...>& t)
{
    printPairsHelper(t, std::make_index_sequence<sizeof...(Args)>{});
}

Demo

CodePudding user response:

There is no way to print elements of a tuple in a loop because, as it was already explained in one of the comments, loops (for, while etc.) are evaluated at run-time and to iterate over tuple you'd need something that works at compile-time.

One solution that I see would be to first write a little utility function(s):

#include <tuple>
#include <utility>

template<std::size_t... Ints, typename... Args, typename Proc>
void forEachImpl(std::tuple<Args...> const& tuple, Proc&& proc, std::index_sequence<Ints...>) {
    (..., proc(std::get<Ints>(tuple)));
}

template<typename... Args, typename Proc>
void forEach(std::tuple<Args...> const& tuple, Proc&& proc) {
    forEachImpl(tuple, proc, std::index_sequence_for<Args...>());
}

The one which we're going to use is forEach (forEachImpl is just an implementation helper function used by forEach). What it does is, it calls proc with each element of tuple as an argument.

Then we can go back to your function - printPairs - and the main function:

#include <iostream>

template<typename... Args>
void printPairs(std::tuple<Args...> const& tuple) {
    forEach(tuple, [] (auto const& pair) {
        std::cout << pair.first << ' ' << pair.second << '\n';
    });
}

int main() {
    std::tuple t(std::pair(1, 3), std::pair('x', 'y'), std::pair(-5.3f, 3.7L));
    printPairs(t);
}
  •  Tags:  
  • Related