Why is this code invalid without constexpr
:
template<typename ...Tpack>
auto CalculateSum(Tpack ...pack)
{
if constexpr (sizeof...(Tpack) > 0)
return (pack + ...);
else
return 0;
}
int main()
{
std::cout << CalculateSum(2, 3, 4, 5, 7.5, 6) << '\n';
}
whereas if there are only int
in the arguments, it gets valid.
Compiler says: 'auto' in return type deduced as 'int' here but deduced as 'double' in earlier return statement
But how does constexpr
resolves?
The reason you need the if constexpr
instead of a plain if
is that you are trying to return two different types, which is not allowed with automatic return type deduction.
With return (pack + ...);
the return type is going to be double
because one of your parameters is a double
. On the other hand, return 0;
is going to return an int
. Since those type do not match, you get an error. You need to if constexpr
to make either return (pack + ...);
or return 0;
be the only line of code that actually gets compiled, which leaves you with just a single type that the function could return.
If you switch to using a trailing return type, you can get rid of the if constexpr
and use a plain if
like
template<typename ...Tpack>
auto CalculateSum(Tpack ...pack) -> decltype((pack + ...))
{
if (sizeof...(Tpack) > 0)
return (pack + ...);
else
return {};
}
But that isn't DRY and is more typing, so I prefer the if constexpr
version.