Thread: printing std::tuple recursively

  1. #1
    Registered User
    Join Date
    Dec 2013
    Posts
    241

    printing std::tuple recursively

    cosider this code snippet

    Code:
    template <std::size_t N=0, class T>
    void print_tuple(const T& t){
        if (N == std::tuple_size<T>::value){
            return;
        }
        
        std::wcout << std::get<N>(t) << L" ";
        print_tuple<N + 1,T>(t);
    
    }
    needless to say, T is always std::tuple with printable variable.
    and also , needless to say, this does not compile . any ideas?
    thanks.

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    You've already had variations on the same problem.

    What does the implementation for `print_tuple<std::tuple_size<T>::value, T>' look like?

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  3. #3
    Registered User
    Join Date
    Dec 2013
    Posts
    241
    in the other variation , I tried recursively iterate over a variadic template. the solution (which I'm still using today, and it's pretty neat and clever) is to create a "splitting" mechanism-
    first overload the function as one which gets Args... args as an argument
    second overload the function as one which gets T t, Args... args as arguments (here the compiler recursively splitting the group (arg1, arg2 ... arg_n) to arg1 and all the rest)
    third overload the function as not getting any arguments , hence stop the recursion

    you can't apply this solution directly with std::tuple - you don't get the arguments as seperated variable but as one pack, which you need to extract each one with std::get..

    What does the implementation for `print_tuple<std::tuple_size<T>::value, T>' look like?
    other then what I wrote here, there is no other implementation. logicly it's supposed to work , no?

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    other then what I wrote here, there is no other implementation. logicly it's supposed to work , no?
    O_o

    I hate that I still have to explain to people that I neither need nor want the answer to questions with such intent.

    *shrug*

    I'll get you started:

    Code:
    print_tuple(make_tuple(0, 1, 2, 3));
    Code:
    template <> void print_tuple<0, std::tuple<int, int, int, int>>
    (
        const std::tuple<int, int, int, int> & f
    )
    {
        std::get<0>(f); /* ... */
        print_tuple<1, std::tuple<int, int, int, int>>(f);
    }
    Code:
    template <> void print_tuple<1, std::tuple<int, int, int, int>>
    (
        const std::tuple<int, int, int, int> & f
    )
    {
        std::get<1>(f); /* ... */
        print_tuple<2, std::tuple<int, int, int, int>>(f);
    }
    Code:
    template <> void print_tuple<2, std::tuple<int, int, int, int>>
    (
        const std::tuple<int, int, int, int> & f
    )
    {
        std::get<2>(f); /* ... */
        print_tuple<3, std::tuple<int, int, int, int>>(f);
    }
    Code:
    template <> void print_tuple<3, std::tuple<int, int, int, int>>
    (
        const std::tuple<int, int, int, int> & f
    )
    {
        std::get<3>(f); /* ... */
        print_tuple<4, std::tuple<int, int, int, int>>(f);
    }
    Your turn...

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  5. #5
    Registered User
    Join Date
    Dec 2013
    Posts
    241
    first, I didn't intent to write a shallow answer, I explained exactly why the other solution won't work.
    anyway, you example does not include lines 3-5 which supposed to break the recursion

    Code:
    template <> void print_tuple<0, std::tuple<int, int, int, int>>
    (
        const std::tuple<int, int, int, int> & f
    )
    {
    if (0 == std::tuple_size<std::tuple<int, int, int, int>>::value){ //returns false
      return ;
    }
        std::get<0>(f); /* ... */
        print_tuple<1, std::tuple<int, int, int, int>>(f);
    }
    Code:
    template <> void print_tuple<1, std::tuple<int, int, int, int>>
    (
        const std::tuple<int, int, int, int> & f
    )
    {
    if (1 == std::tuple_size<std::tuple<int, int, int, int>>::value){ //returns false
      return ;
    }
        std::get<1>(f); /* ... */
        print_tuple<1, std::tuple<int, int, int, int>>(f);
    }
    Code:
    template <> void print_tuple<2, std::tuple<int, int, int, int>>
    (
        const std::tuple<int, int, int, int> & f
    )
    {
    if (2 == std::tuple_size<std::tuple<int, int, int, int>>::value){ //returns false
      return ;
    }
        std::get<2>(f); /* ... */
        print_tuple<1, std::tuple<int, int, int, int>>(f);
    }
    Code:
    template <> void print_tuple<3, std::tuple<int, int, int, int>>
    (
        const std::tuple<int, int, int, int> & f
    )
    {
    if (0 == std::tuple_size<std::tuple<int, int, int, int>>::value){ //returns false
      return ;
    }
        std::get<3>(f); /* ... */
        print_tuple<1, std::tuple<int, int, int, int>>(f);
    }
    Code:
    template <> void print_tuple<4, std::tuple<int, int, int, int>>
    (
        const std::tuple<int, int, int, int> & f
    )
    {
    if (4 == std::tuple_size<std::tuple<int, int, int, int>>::value){ //returns true - simply returns
      return ;
    }
        std::get<4>(f); /* ... */
        print_tuple<1, std::tuple<int, int, int, int>>(f);
    }

  6. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    anyway, you example does not include lines 3-5 which supposed to break the recursion
    O_o

    The apparent omission was purposeful; the recursion you are are talking about is irrelevant.

    Code:
    std::get<4>(f);
    What does the `std::get<4>(f);' fragment do?

    If you don't know, write some code to test the exact behavior of that fragment with `std::tuple<???>' having only four elements.

    If you think you know, write some code to test the exact behavior of that fragment with `std::tuple<???>' having only four elements.

    Now, you can place a return statement above the `std::get<4>(f);' line in your test code.

    Your post has copy/paste errors, but let's look at one more fragment: what does `print_tuple<5, std::tuple<int, int, int, int>>(f);' do?

    You've been given this answer a few different ways for a few different presentations. I'm not going to answer you, and I hope no one else answers you. I have given you a little homework; if you do the homework, you will not again need to be told.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Boost tuple and Vector problem
    By LuckyPierre in forum C++ Programming
    Replies: 14
    Last Post: 09-29-2009, 01:26 AM
  2. boost tuple question
    By Elkvis in forum C++ Programming
    Replies: 1
    Last Post: 09-23-2009, 11:08 AM
  3. tuple usage
    By KIBO in forum C++ Programming
    Replies: 1
    Last Post: 06-24-2009, 02:49 AM
  4. computing the GCD non-recursively
    By rrreeefff in forum C Programming
    Replies: 2
    Last Post: 10-05-2008, 10:57 PM
  5. Summing a BST recursively?
    By roy.42 in forum C Programming
    Replies: 4
    Last Post: 08-18-2007, 02:30 AM