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
T
forsizeof...(rest)
. But if you callprintArgs(onlyOne)
thenT
is deduced fromonlyOne
andArgs
is empty, andsizeof...(rest)
is0
. Your function can be called with 1 (T first
) plus zero or more, (Args... rest
), arguments.If you remove the
constexpr
you get the following error:Because on the last recursion only 1 argument is passed to
printArgs
andrest
has no elements. In that caseprintArgs(rest...)
fails to compile because (see above) your function can only be called with 1 or more.if constexpr
results in the false branch being discarded and the part where you callprintArgs()
is never instantiated.