I\'m trying to write a variadic template constexpr function which calculates sum of the template parameters given. Here\'s my code:
template<
templateconstexpr int f() { return First + f (); } template constexpr int f() { return First; } int main() { f<1, 2, 3>(); return 0; }
You get this error:
error C2668: 'f': ambiguous call to overloaded function while trying to resolve f<3,>() call.
This is because a variadic parameter pack can be given 0 arguments, so f<3> could work with template by "expanding" to template<3, >. However, you also have the specialization of template, so the compiler does not know which one to choose.
Explicitly stating the first and second template arguments is a completely valid and good solution to this problem.
When you try to change the base case to:
template <>
constexpr int f()
{
return 0;
}
You have a problem because functions cannot be specialized in that way. Classes and structs can be, but not functions.
constexprtemplate
constexpr int sum(Is... values) {
return (0 + ... + values);
}
constexpr functionconstexpr int sum() {
return 0;
}
template
constexpr int sum(I first, Is... rest) {
return first + sum(rest...);
}
template
struct sum;
template <>
struct sum<>
: std::integral_constant
{};
template
struct sum
: std::integral_constant::value>
{};