Search code examples
c++templatescomparatorc2664

why can't i pass two different comparators to one template function?


I'm wracking my brain here for several hours, but I still don't understand why I'm getting an error when I'm trying to run this code. After some time I managed to narrow it down to the expression:

pastryPrice()

which causes the problem - as you can see, I'm trying to build numerous comparators for one template function of sorting

    struct dialingAreaComp{
    inline bool operator()(const Deliver *d1, const Deliver *d2)const {
        return d1->getDialingArea() < d2->getDialingArea();
    }
};
struct pastryPrice {
    inline bool operator()(const Pastry *p1, const Pastry *p2)const {
        return p1->getPrice() < p2->getPrice();
    }
};
template<class T>
void sortCollection(T& collection)
{
    if ( typeid (collection) == typeid(vector <Deliver*>))
    {
        sort(collection.begin(), collection.end(), dialingAreaComp());
        printCollection(collection);
    }
    else if (typeid (collection) == typeid(vector <Pastry*>))
    {
        sort(collection.begin(), collection.end(), pastryPrice());
        printCollection(collection);
    }
    else { cout << "WRONG!"; }
}

I'm getting five errors, all the same:

Severity Code Description Project File Line Suppression State Error C2664 'bool Bakery::pastryPrice::operator ()(const Pastry *,const Pastry *) const': cannot convert argument 1 from 'Deliver *' to 'const Pastry *' Bakery c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility 809

And one more:

Severity Code Description Project File Line Suppression State Error C2056 illegal expression Bakery c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility 809

When I take off the expression I wrote above, the code works just fine - why can't I pass two different comparators to one template function?

Now:

C2264 is a Compiler Error that occurs when one tries to pass a function a parameter of an incompatible type.

But the Deliver function works and when I took off the Deliver comparator the Pastry compiled as well... so what is the incompatible type?


Solution

  • You get an error because the templated function is evaluated at compile time, and one of the function calls will never match. Instead of the template use simple function overloads:

    void sortCollection(vector <Deliver*>& collection)
    {
        sort(collection.begin(), collection.end(), dialingAreaComp());
        printCollection(collection);
    }
    
    void sortCollection(vector <Pastry*>& collection)
    {
        sort(collection.begin(), collection.end(), pastryPrice());
        printCollection(collection);
    }