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?
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?
- 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
add a comment |
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?
- 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
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
add a comment |
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?
- 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
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?
- 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
c++ variadic-templates typetraits
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
add a comment |
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
add a comment |
3 Answers
3
active
oldest
votes
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
add a comment |
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 + ...);
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
add a comment |
- The
sum()
function is required here so that I can have a return value for avoid
passed in when processing the last variadic member - Is it possible to avoid writing thissum()
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.
- 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.
3
How does the solution withreturn ;
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
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
add a comment |
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
add a comment |
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
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
answered Mar 6 at 15:24
Guillaume RacicotGuillaume Racicot
14.9k53468
14.9k53468
add a comment |
add a comment |
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 + ...);
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
add a comment |
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 + ...);
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
add a comment |
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 + ...);
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 + ...);
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
add a comment |
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
add a comment |
- The
sum()
function is required here so that I can have a return value for avoid
passed in when processing the last variadic member - Is it possible to avoid writing thissum()
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.
- 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.
3
How does the solution withreturn ;
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
add a comment |
- The
sum()
function is required here so that I can have a return value for avoid
passed in when processing the last variadic member - Is it possible to avoid writing thissum()
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.
- 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.
3
How does the solution withreturn ;
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
add a comment |
- The
sum()
function is required here so that I can have a return value for avoid
passed in when processing the last variadic member - Is it possible to avoid writing thissum()
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.
- 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.
- The
sum()
function is required here so that I can have a return value for avoid
passed in when processing the last variadic member - Is it possible to avoid writing thissum()
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.
- 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.
edited Mar 7 at 7:33
answered Mar 6 at 15:24
AngewAngew
133k11257349
133k11257349
3
How does the solution withreturn ;
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
add a comment |
3
How does the solution withreturn ;
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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