Пытаясь научить себя STL, я написал следующий класс:
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;
};
оператор< определяется как:
bool Person::operator<(const Person& p) const{
if (weight<p.weight)
return true;
else
return false;
}
Почему это не работает:
// get lower_bound for weight = 50
vector<Person>::iterator itr = lower_bound(v.begin(),v.end(),50,compareWeight);
Это бросает:
error C2914: 'std::lower_bound':cannot deduce template argument as function argument is ambiguous
Я могу решить эту проблему с помощью фиктивного человека с весом = 50, а затем вызову lower_bound:
vector<Person>::iterator itr = lower_bound(v.begin(),v.end(), dummy);
Но это, очевидно, не очень элегантно, может кто-нибудь, пожалуйста, помогите мне сравнить вес с работой? Также любые предложения о наилучшем подходе в таком случае будут отличными. Нет Boost или C ++ 11, пожалуйста, извините.
Вместо предоставления двух дружественных функций вы можете предоставить один функциональный объект, который будет выполнять обе операции.
struct CompareWeight {
bool operator()(const Person&, int) const;
bool operator()(int, const Person&) const;
};
Тогда вы можете назвать алгоритм как:
std::lower_bound(std::begin(v), std::end(v), CompareWeight());
Примечание. Я согласен с jrok в том, что необходима только одна перегрузка, но, похоже, что ваша реализация (которая не обязательно полностью соответствует стандарту) требует другого направления, если это так, это предусматривает простой обходной путь.
Компилятор должен знать точную сигнатуру функции, чтобы вывести последний аргумент lower_bound
, Но с тех пор compareWeight
перегружен, он не может решить, какой взять. Таким образом, вам нужно вручную привести приведение к правильному указателю функции:
typedef bool(*Comp)(const Person&, const int&);
lower_bound(v.begin(),v.end(),50,static_cast<Comp>(&compareWeight));
Лично я бы сделал то, что вы сделали с фиктивным параметром.
Не по теме предложение: передавайте примитивные типы по значению, это быстрее.
friend bool compareWeight(const Person &p, int wt);