I have a simple recursive function to print each argument from a parameter pack
#include <iostream>
template<typename T, typename... Args>
void printArgs(T first, Args... rest) {
std::cout << first << " ";
if constexpr (sizeof...(rest) > 0) { // doesn't compile without constexpr
printArgs(rest...);
} else {
return;
}
}
int main() {
printArgs(1, 2, "hello");
return 0;
}
Q1: Why do I need constexpr in the if for the program to compile?
Q2: Shouldn't the condition be sizeof...(rest) > 1? Because if the size is 1 and I call printArgs again, then wouldn't rest be empty? (is it ok for it to be empty?)
I saw similar questions, like "constexpr if" vs "if" with optimizations - why is "constexpr" needed?, but I don't see how those answers relate to my case.
I'll start with the second Q, because the answer to that also explains Q1.
Your mistake is to count
Tforsizeof...(rest). But if you callprintArgs(onlyOne)thenTis deduced fromonlyOneandArgsis empty, andsizeof...(rest)is0. Your function can be called with 1 (T first) plus zero or more, (Args... rest), arguments.If you remove the
constexpryou get the following error:Because on the last recursion only 1 argument is passed to
printArgsandresthas no elements. In that caseprintArgs(rest...)fails to compile because (see above) your function can only be called with 1 or more.if constexprresults in the false branch being discarded and the part where you callprintArgs()is never instantiated.