Variadic Templates - Recursive function - Last variadic member2019 Community Moderator ElectionWhy can templates only be implemented in the header file?Meaning of 'const' last in a function declaration of a class?Variadic template candidate unmatchedCalling variadic argument function from template classVariadic template function: specialize head/tail and empty base caseC++ Variadic Function Templates of Known TypePass overloaded member function to a variadic template functionDefining member variable using decltype on variadic function template of a class templateFor every template type an argument of a set typeAccept both int and class in variadic templated function?

Do I really need to have a scientific explanation for my premise?

Do items de-spawn in Diablo?

Why is computing ridge regression with a Cholesky decomposition much quicker than using SVD?

How to write ı (i without dot) character in pgf-pie

What's wrong with this bogus proof?

Doesn't allowing a user mode program to access kernel space memory and execute the IN and OUT instructions defeat the purpose of having CPU modes?

Reverse string, can I make it faster?

What Happens when Passenger Refuses to Fly Boeing 737 Max?

If I receive an SOS signal, what is the proper response?

Why does liquid water form when we exhale on a mirror?

Reversed Sudoku

How are showroom/display vehicles prepared?

How to secure an aircraft at a transient parking space?

How is the wildcard * interpreted as a command?

How does NOW work?

Was Luke Skywalker the leader of the Rebel forces on Hoth?

How to detect if C code (which needs 'extern C') is compiled in C++

What problems would a superhuman have whose skin is constantly hot?

Does the nature of the Apocalypse in The Umbrella Academy change from the first to the last episode?

What was the Kree's motivation in Captain Marvel?

How many characters using PHB rules does it take to be able to have access to any PHB spell at the start of an adventuring day?

Plausibility of Mushroom Buildings

Error during using callback start_page_number in lualatex

Latex does not go to next line



Variadic Templates - Recursive function - Last variadic member



2019 Community Moderator ElectionWhy can templates only be implemented in the header file?Meaning of 'const' last in a function declaration of a class?Variadic template candidate unmatchedCalling variadic argument function from template classVariadic template function: specialize head/tail and empty base caseC++ Variadic Function Templates of Known TypePass overloaded member function to a variadic template functionDefining member variable using decltype on variadic function template of a class templateFor every template type an argument of a set typeAccept both int and class in variadic templated function?










4















I have the following code with a variadic template copied from:
https://www.youtube.com/watch?v=iWvcoIKSaoc @41:30



auto sum() return 0; 

template<typename Head, typename... Tail>
auto sum(Head head, Tail... tail)

return head+sum(tail...);


int main()
cout<< sum(1,2.4) << endl;
//cout<< sum("hello ", "world") << endl;
return 0;



I have two questions:
1. The sum() function is required here so that I can have a return value for a void passed in when processing the last variadic member - Is it possible to avoid writing this sum() function and have the same functionality?



  1. Returning a integer '0' from the sum() function restricts the entire template to be used by integers - Can I extend the same template to concatenate strings?

Thank You










share|improve this question



















  • 1





    Does C++14 tag mean you don't want to hear about C++17 fold expressions?

    – HolyBlackCat
    Mar 6 at 15:22











  • No - I am ok with C++17

    – Nujufas
    Mar 6 at 15:23















4















I have the following code with a variadic template copied from:
https://www.youtube.com/watch?v=iWvcoIKSaoc @41:30



auto sum() return 0; 

template<typename Head, typename... Tail>
auto sum(Head head, Tail... tail)

return head+sum(tail...);


int main()
cout<< sum(1,2.4) << endl;
//cout<< sum("hello ", "world") << endl;
return 0;



I have two questions:
1. The sum() function is required here so that I can have a return value for a void passed in when processing the last variadic member - Is it possible to avoid writing this sum() function and have the same functionality?



  1. Returning a integer '0' from the sum() function restricts the entire template to be used by integers - Can I extend the same template to concatenate strings?

Thank You










share|improve this question



















  • 1





    Does C++14 tag mean you don't want to hear about C++17 fold expressions?

    – HolyBlackCat
    Mar 6 at 15:22











  • No - I am ok with C++17

    – Nujufas
    Mar 6 at 15:23













4












4








4








I have the following code with a variadic template copied from:
https://www.youtube.com/watch?v=iWvcoIKSaoc @41:30



auto sum() return 0; 

template<typename Head, typename... Tail>
auto sum(Head head, Tail... tail)

return head+sum(tail...);


int main()
cout<< sum(1,2.4) << endl;
//cout<< sum("hello ", "world") << endl;
return 0;



I have two questions:
1. The sum() function is required here so that I can have a return value for a void passed in when processing the last variadic member - Is it possible to avoid writing this sum() function and have the same functionality?



  1. Returning a integer '0' from the sum() function restricts the entire template to be used by integers - Can I extend the same template to concatenate strings?

Thank You










share|improve this question
















I have the following code with a variadic template copied from:
https://www.youtube.com/watch?v=iWvcoIKSaoc @41:30



auto sum() return 0; 

template<typename Head, typename... Tail>
auto sum(Head head, Tail... tail)

return head+sum(tail...);


int main()
cout<< sum(1,2.4) << endl;
//cout<< sum("hello ", "world") << endl;
return 0;



I have two questions:
1. The sum() function is required here so that I can have a return value for a void passed in when processing the last variadic member - Is it possible to avoid writing this sum() function and have the same functionality?



  1. Returning a integer '0' from the sum() function restricts the entire template to be used by integers - Can I extend the same template to concatenate strings?

Thank You







c++ variadic-templates typetraits






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 6 at 15:23









HolyBlackCat

16.7k33468




16.7k33468










asked Mar 6 at 15:20









NujufasNujufas

12529




12529







  • 1





    Does C++14 tag mean you don't want to hear about C++17 fold expressions?

    – HolyBlackCat
    Mar 6 at 15:22











  • No - I am ok with C++17

    – Nujufas
    Mar 6 at 15:23












  • 1





    Does C++14 tag mean you don't want to hear about C++17 fold expressions?

    – HolyBlackCat
    Mar 6 at 15:22











  • No - I am ok with C++17

    – Nujufas
    Mar 6 at 15:23







1




1





Does C++14 tag mean you don't want to hear about C++17 fold expressions?

– HolyBlackCat
Mar 6 at 15:22





Does C++14 tag mean you don't want to hear about C++17 fold expressions?

– HolyBlackCat
Mar 6 at 15:22













No - I am ok with C++17

– Nujufas
Mar 6 at 15:23





No - I am ok with C++17

– Nujufas
Mar 6 at 15:23












3 Answers
3






active

oldest

votes


















3














The trick is to never allow empty sum() calls, and treat the sum(last) as the last recursion:



template<typename Last>
auto sum(Last last)
return last;


template<typename Head, typename Second, typename... Tail>
auto sum(Head head, Second second, Tail... tail)

return head + sum(second, tail...);


int main()
cout<< sum(1,2.4) << endl;
cout<< sum("hello ", "world") << endl;
return 0;



Live example






share|improve this answer






























    6














    To complement @GuillaumeRacicot answer I prefer to end a recursion with if constexpr which is a c++17 feature.



    template<typename Head, typename Second, typename... Tail>
    auto sum(Head head, Second second, Tail... tail)

    if constexpr(sizeof...(tail) > 0)
    return head + sum(second, tail...);
    return head + second;



    You can also consider fold expressions:



    template<typename ...Pack>
    auto sum(Pack... args)
    return (args + ...);






    share|improve this answer




















    • 2





      If you're in C++17 you might as well use a fold expression...

      – Max Langhof
      Mar 6 at 15:53











    • @MaxLanghof excellent point, I added an example as well

      – KostasRim
      Mar 6 at 16:06


















    1















    1. The sum() function is required here so that I can have a return value for a void passed in when processing the last variadic member - Is it possible to avoid writing this sum() function and have the same functionality?



    Every recursion needs a stop condition. In the typical use of recursion with variadic templates (such as in this code), the stop condition is a different overload of the primary template. So you cannot get rid of this entirely.



    You can of course replace the stop condition with a different one. Perhaps this one, which will also work for summing things which are not default-constructible:



    template <class T>
    auto sum(T last) return last;


    Of course, there are other approaches to this than recursive variadic templates; such approaches may not need a stop condition.




    1. Returning a integer '0' from the sum() function restricts the entire template to be used by integers - Can I extend the same template to concatenate strings?



    No, because the non-template function has no knowledge of which type the previous recursive invocations were dealing with. This can be solved by using the "last item" stop condition I suggested above.






    share|improve this answer




















    • 3





      How does the solution with return ; work? I cannot make it work: ideone.com/vrCXSb

      – mch
      Mar 6 at 16:15











    • @mch Of course, that was an error on my part. Fixed.

      – Angew
      Mar 7 at 7:33










    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55026478%2fvariadic-templates-recursive-function-last-variadic-member%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    The trick is to never allow empty sum() calls, and treat the sum(last) as the last recursion:



    template<typename Last>
    auto sum(Last last)
    return last;


    template<typename Head, typename Second, typename... Tail>
    auto sum(Head head, Second second, Tail... tail)

    return head + sum(second, tail...);


    int main()
    cout<< sum(1,2.4) << endl;
    cout<< sum("hello ", "world") << endl;
    return 0;



    Live example






    share|improve this answer



























      3














      The trick is to never allow empty sum() calls, and treat the sum(last) as the last recursion:



      template<typename Last>
      auto sum(Last last)
      return last;


      template<typename Head, typename Second, typename... Tail>
      auto sum(Head head, Second second, Tail... tail)

      return head + sum(second, tail...);


      int main()
      cout<< sum(1,2.4) << endl;
      cout<< sum("hello ", "world") << endl;
      return 0;



      Live example






      share|improve this answer

























        3












        3








        3







        The trick is to never allow empty sum() calls, and treat the sum(last) as the last recursion:



        template<typename Last>
        auto sum(Last last)
        return last;


        template<typename Head, typename Second, typename... Tail>
        auto sum(Head head, Second second, Tail... tail)

        return head + sum(second, tail...);


        int main()
        cout<< sum(1,2.4) << endl;
        cout<< sum("hello ", "world") << endl;
        return 0;



        Live example






        share|improve this answer













        The trick is to never allow empty sum() calls, and treat the sum(last) as the last recursion:



        template<typename Last>
        auto sum(Last last)
        return last;


        template<typename Head, typename Second, typename... Tail>
        auto sum(Head head, Second second, Tail... tail)

        return head + sum(second, tail...);


        int main()
        cout<< sum(1,2.4) << endl;
        cout<< sum("hello ", "world") << endl;
        return 0;



        Live example







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 6 at 15:24









        Guillaume RacicotGuillaume Racicot

        14.9k53468




        14.9k53468























            6














            To complement @GuillaumeRacicot answer I prefer to end a recursion with if constexpr which is a c++17 feature.



            template<typename Head, typename Second, typename... Tail>
            auto sum(Head head, Second second, Tail... tail)

            if constexpr(sizeof...(tail) > 0)
            return head + sum(second, tail...);
            return head + second;



            You can also consider fold expressions:



            template<typename ...Pack>
            auto sum(Pack... args)
            return (args + ...);






            share|improve this answer




















            • 2





              If you're in C++17 you might as well use a fold expression...

              – Max Langhof
              Mar 6 at 15:53











            • @MaxLanghof excellent point, I added an example as well

              – KostasRim
              Mar 6 at 16:06















            6














            To complement @GuillaumeRacicot answer I prefer to end a recursion with if constexpr which is a c++17 feature.



            template<typename Head, typename Second, typename... Tail>
            auto sum(Head head, Second second, Tail... tail)

            if constexpr(sizeof...(tail) > 0)
            return head + sum(second, tail...);
            return head + second;



            You can also consider fold expressions:



            template<typename ...Pack>
            auto sum(Pack... args)
            return (args + ...);






            share|improve this answer




















            • 2





              If you're in C++17 you might as well use a fold expression...

              – Max Langhof
              Mar 6 at 15:53











            • @MaxLanghof excellent point, I added an example as well

              – KostasRim
              Mar 6 at 16:06













            6












            6








            6







            To complement @GuillaumeRacicot answer I prefer to end a recursion with if constexpr which is a c++17 feature.



            template<typename Head, typename Second, typename... Tail>
            auto sum(Head head, Second second, Tail... tail)

            if constexpr(sizeof...(tail) > 0)
            return head + sum(second, tail...);
            return head + second;



            You can also consider fold expressions:



            template<typename ...Pack>
            auto sum(Pack... args)
            return (args + ...);






            share|improve this answer















            To complement @GuillaumeRacicot answer I prefer to end a recursion with if constexpr which is a c++17 feature.



            template<typename Head, typename Second, typename... Tail>
            auto sum(Head head, Second second, Tail... tail)

            if constexpr(sizeof...(tail) > 0)
            return head + sum(second, tail...);
            return head + second;



            You can also consider fold expressions:



            template<typename ...Pack>
            auto sum(Pack... args)
            return (args + ...);







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 6 at 16:07

























            answered Mar 6 at 15:50









            KostasRimKostasRim

            1,5551926




            1,5551926







            • 2





              If you're in C++17 you might as well use a fold expression...

              – Max Langhof
              Mar 6 at 15:53











            • @MaxLanghof excellent point, I added an example as well

              – KostasRim
              Mar 6 at 16:06












            • 2





              If you're in C++17 you might as well use a fold expression...

              – Max Langhof
              Mar 6 at 15:53











            • @MaxLanghof excellent point, I added an example as well

              – KostasRim
              Mar 6 at 16:06







            2




            2





            If you're in C++17 you might as well use a fold expression...

            – Max Langhof
            Mar 6 at 15:53





            If you're in C++17 you might as well use a fold expression...

            – Max Langhof
            Mar 6 at 15:53













            @MaxLanghof excellent point, I added an example as well

            – KostasRim
            Mar 6 at 16:06





            @MaxLanghof excellent point, I added an example as well

            – KostasRim
            Mar 6 at 16:06











            1















            1. The sum() function is required here so that I can have a return value for a void passed in when processing the last variadic member - Is it possible to avoid writing this sum() function and have the same functionality?



            Every recursion needs a stop condition. In the typical use of recursion with variadic templates (such as in this code), the stop condition is a different overload of the primary template. So you cannot get rid of this entirely.



            You can of course replace the stop condition with a different one. Perhaps this one, which will also work for summing things which are not default-constructible:



            template <class T>
            auto sum(T last) return last;


            Of course, there are other approaches to this than recursive variadic templates; such approaches may not need a stop condition.




            1. Returning a integer '0' from the sum() function restricts the entire template to be used by integers - Can I extend the same template to concatenate strings?



            No, because the non-template function has no knowledge of which type the previous recursive invocations were dealing with. This can be solved by using the "last item" stop condition I suggested above.






            share|improve this answer




















            • 3





              How does the solution with return ; work? I cannot make it work: ideone.com/vrCXSb

              – mch
              Mar 6 at 16:15











            • @mch Of course, that was an error on my part. Fixed.

              – Angew
              Mar 7 at 7:33















            1















            1. The sum() function is required here so that I can have a return value for a void passed in when processing the last variadic member - Is it possible to avoid writing this sum() function and have the same functionality?



            Every recursion needs a stop condition. In the typical use of recursion with variadic templates (such as in this code), the stop condition is a different overload of the primary template. So you cannot get rid of this entirely.



            You can of course replace the stop condition with a different one. Perhaps this one, which will also work for summing things which are not default-constructible:



            template <class T>
            auto sum(T last) return last;


            Of course, there are other approaches to this than recursive variadic templates; such approaches may not need a stop condition.




            1. Returning a integer '0' from the sum() function restricts the entire template to be used by integers - Can I extend the same template to concatenate strings?



            No, because the non-template function has no knowledge of which type the previous recursive invocations were dealing with. This can be solved by using the "last item" stop condition I suggested above.






            share|improve this answer




















            • 3





              How does the solution with return ; work? I cannot make it work: ideone.com/vrCXSb

              – mch
              Mar 6 at 16:15











            • @mch Of course, that was an error on my part. Fixed.

              – Angew
              Mar 7 at 7:33













            1












            1








            1








            1. The sum() function is required here so that I can have a return value for a void passed in when processing the last variadic member - Is it possible to avoid writing this sum() function and have the same functionality?



            Every recursion needs a stop condition. In the typical use of recursion with variadic templates (such as in this code), the stop condition is a different overload of the primary template. So you cannot get rid of this entirely.



            You can of course replace the stop condition with a different one. Perhaps this one, which will also work for summing things which are not default-constructible:



            template <class T>
            auto sum(T last) return last;


            Of course, there are other approaches to this than recursive variadic templates; such approaches may not need a stop condition.




            1. Returning a integer '0' from the sum() function restricts the entire template to be used by integers - Can I extend the same template to concatenate strings?



            No, because the non-template function has no knowledge of which type the previous recursive invocations were dealing with. This can be solved by using the "last item" stop condition I suggested above.






            share|improve this answer
















            1. The sum() function is required here so that I can have a return value for a void passed in when processing the last variadic member - Is it possible to avoid writing this sum() function and have the same functionality?



            Every recursion needs a stop condition. In the typical use of recursion with variadic templates (such as in this code), the stop condition is a different overload of the primary template. So you cannot get rid of this entirely.



            You can of course replace the stop condition with a different one. Perhaps this one, which will also work for summing things which are not default-constructible:



            template <class T>
            auto sum(T last) return last;


            Of course, there are other approaches to this than recursive variadic templates; such approaches may not need a stop condition.




            1. Returning a integer '0' from the sum() function restricts the entire template to be used by integers - Can I extend the same template to concatenate strings?



            No, because the non-template function has no knowledge of which type the previous recursive invocations were dealing with. This can be solved by using the "last item" stop condition I suggested above.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 7 at 7:33

























            answered Mar 6 at 15:24









            AngewAngew

            133k11257349




            133k11257349







            • 3





              How does the solution with return ; work? I cannot make it work: ideone.com/vrCXSb

              – mch
              Mar 6 at 16:15











            • @mch Of course, that was an error on my part. Fixed.

              – Angew
              Mar 7 at 7:33












            • 3





              How does the solution with return ; work? I cannot make it work: ideone.com/vrCXSb

              – mch
              Mar 6 at 16:15











            • @mch Of course, that was an error on my part. Fixed.

              – Angew
              Mar 7 at 7:33







            3




            3





            How does the solution with return ; work? I cannot make it work: ideone.com/vrCXSb

            – mch
            Mar 6 at 16:15





            How does the solution with return ; work? I cannot make it work: ideone.com/vrCXSb

            – mch
            Mar 6 at 16:15













            @mch Of course, that was an error on my part. Fixed.

            – Angew
            Mar 7 at 7:33





            @mch Of course, that was an error on my part. Fixed.

            – Angew
            Mar 7 at 7:33

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55026478%2fvariadic-templates-recursive-function-last-variadic-member%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            1928 у кіно

            Захаров Федір Захарович

            Ель Греко