samedi 7 septembre 2019

Why is "no matching overload found" error appearing even though I have them defined

Going through some template tutorial I encountered the fol;owing 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 pair<int, int> int_pair;
//typedef tuple<int, int, int> trie;

int_pair sum_and_product(int a, int b)
{
    return int_pair(a + b, a * b);
}

//trie sum_product_avg(int a, int b, int c) {
//  trie t{ a + b + c, a * b * c, (a + b + c) / 3 };
//  return t;
//}

template<typename T1, typename T2, typename T3>
struct triple
{

    typedef T1 result_type;
    T1 first;
    T2 second;
    T3 third;

    triple(const T1& first, const T2& second, const T3& third) 
        : first{ first }, second{ second }, third{ third }
    {}
};


typedef triple<int, int, int> trie;

//trie sum_product_avg(int a, int b, int c) {
//  return trie(a + b + c, a * b * c, (a + b + c) / 2);
//}

template<typename T1, typename T2, typename T3>
triple<T1, T2, T3> sum_product_average(
    const T1& a, const T2& b, const T3& c
)
{
    return triple<T1, T2, T3>(a+b+c, a*b*c, (a+b+c)/triple<T1, T2, T3>::result_type(3));
}


void consuming_templates()
{
    int a = 2, b = 3;
    auto result = sum_and_product(a, b);
    cout << "sum= " << result.first <<
        " product=" << result.second;

    int c = 4;
    //auto result2 = sum_product_avg(a, b, c);
    //cout << "sum = " << get<0>(result2) <<
    //  " product = " << get<1>(result2) <<
    //  " average = " << get<2>(result2) << endl;

    //auto result2 = sum_product_avg(a, b, c);
    //cout << "sum = " << result2.first <<
    //  " product = " << result2.second <<
    //  " average = " << result2.third << endl;

}

void template_functions()
{
    int a = 14;
    double b = 5.0;
    float c = -3.5f;

    auto result = sum_product_average(a, b, c);
    cout << "sum = " << result.first <<
        " product = " << result.second <<
        " average = " << result.third << endl;
}

typedef complex<double> cd;
typedef triple<cd, cd, cd> cdt;

// template <> shows that it is a template initialization
// no typenames inside <> because the specialization already specifies the type 
template <> cdt sum_product_average(const cd& a, const cd& b, const cd& c)
{
    auto result = sum_product_average(a.real(), b.real(), c.real());
    return cdt(result.first, result.second, result.third);
}



void template_specialization()
{
    cd a(2, 3), b(3, 4), c(4, 5);
    auto result = sum_product_average(a,b,c);
    cout << result.first << ", " << result.second << ", " << result.third << endl;

}

// 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;
}

Aucun commentaire:

Enregistrer un commentaire