Lower_bound throws "error C2914: 'std::lower_bound' : cannot deduce template argument as function argument is ambiguous"

StackOverflow https://stackoverflow.com/questions/18388613

  •  26-06-2022
  •  | 
  •  

Question

While trying to teach myself STL, I wrote the following class:

class Person{
public:
    ...
    bool operator<(const Person& p) const; // sorts by weight
    friend bool compareWeight(const Person &p, const int& wt); //true if wt<p.weight
    friend bool compareWeight(const int& wt, const Person &p);
    ...
private:
    int age;
    int weight;
};

Operator< is defined as:

bool Person::operator<(const Person& p) const{
    if (weight<p.weight)
        return true;
    else
        return false;
}

Why doesn't this work:

// get lower_bound for weight = 50
vector<Person>::iterator itr = lower_bound(v.begin(),v.end(),50,compareWeight); 

It throws:

error C2914: 'std::lower_bound':cannot deduce template argument as function argument is ambiguous

I can solve this using a dummy person, with weight = 50, and then calling lower_bound:

vector<Person>::iterator itr = lower_bound(v.begin(),v.end(), dummy);

But its obviously not very elegant, can someone please help me getting compareWeight to work? Also, any suggestions about best approach in such a case will be great. No Boost or C++11 please, sorry.

Was it helpful?

Solution

Instead of providing the two friend functions, you can provide a single function object that will do both operations.

struct CompareWeight {
   bool operator()(const Person&, int) const;
   bool operator()(int, const Person&) const;
};

Then you can call the algorithm as:

std::lower_bound(std::begin(v), std::end(v), CompareWeight());

Note: I agree with jrok that only one overload should be needed, but it seems that your implementation (which need not fully comply with the standard) requires the other direction, if that is the case this provides for a simple workaround.

OTHER TIPS

Compiler needs to know the exact signature of the function to deduce the last argument of lower_bound. But since compareWeight is overloaded, it can't decide which one to take. Thus, you need to manualy cast to the right function pointer:

typedef bool(*Comp)(const Person&, const int&);
lower_bound(v.begin(),v.end(),50,static_cast<Comp>(&compareWeight)); 

Personaly, I'd do what you did with dummy parameter.


Off topic suggestion: pass primitive types by value, it's faster.

friend bool compareWeight(const Person &p, int wt);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top