Lower_bound throws & quot; ошибка C2914: ‘std :: lower_bound’: невозможно вывести аргумент шаблона, поскольку аргумент функции является неоднозначным & quot;

Пытаясь научить себя 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, пожалуйста, извините.

1

Решение

Вместо предоставления двух дружественных функций вы можете предоставить один функциональный объект, который будет выполнять обе операции.

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 в том, что необходима только одна перегрузка, но, похоже, что ваша реализация (которая не обязательно полностью соответствует стандарту) требует другого направления, если это так, это предусматривает простой обходной путь.

1

Другие решения

Компилятор должен знать точную сигнатуру функции, чтобы вывести последний аргумент 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);
1

По вопросам рекламы [email protected]