Going through some template tutorial I encountered the following error:
Error (active) E0304 no instance of overloaded function "sum" matches the argument list Templates
I know that I am dealing with variadic templates here but I cannot see why the overload for multiple parameters is not being detected. Also worth mentioning that the exact code in the tutorial I am following does not throw any error.
#include <iostream>
#include <string>
#include <memory>
#include <tuple>
#include <array>
#include <vector>
#include <complex>
using namespace std;
typedef complex<double> cd;
// specialization for when there is only one argument
template <typename T>
T sum(T t) { return t; }
// -> defines a return type as a result of sum values
template<typename T, typename ...U>
auto sum(T t, U ...u) -> decltype(t + sum(u...))
{
return t + sum(u...);
}
void variadic()
{
cout << sum(1, 2, 3, 4) << endl;
}
int main()
{
//consuming_templates();
//template_functions();
variadic();
getchar();
return 0;
}
error:
Severity Code Description Project File Line Suppression State
Error C2672 'sum': no matching overloaded function found Templates
Severity Code Description Project File Line Suppression State
Error C2893 Failed to specialize function template 'unknown-type sum(T,U...)' Templates
Severity Code Description Project File Line Suppression State
Error C2780 'T sum(T)': expects 1 arguments - 4 provided Templates C:\Users\erind\source\repos\Templates\Templates\Templates.cpp 35
It's a works for std::common_type
.
I mean... try rewriting your sum()
variadic version as follows
template<typename T, typename ...U>
auto sum(T t, U ...u) -> typename std::common_type<T, U...>::type
{
return t + sum(u...);
}
The problem in your code is that with
template<typename T, typename ...U>
auto sum(T t, U ...u) -> decltype(t + sum(u...))
{
return t + sum(u...);
}
you try to set the return type recursively with decltype(t + sum(u...))
but doesn't works.
Starting from C++14, you can simply use auto
, without trailing return type
template<typename T, typename ...U>
auto sum(T t, U ...u)
{
return t + sum(u...);
}
Starting from C++17, you can use template folding and avoid recursion at all
template <typename ... U>
auto sum (U ... u)
{ return (u + ...); }