2

独学で 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;
};

Operator< は次のように定義されます。

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);

しかし、明らかにあまりエレガントではありません。誰かがcompareWeightを機能させるのを手伝ってくれますか? また、そのような場合の最善のアプローチに関する提案は素晴らしいでしょう。Boost または C++11 はありません。申し訳ありません。

4

2 に答える 2

3

2 つのフレンド関数を提供する代わりに、両方の操作を行う単一の関数オブジェクトを提供できます。

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

次に、アルゴリズムを次のように呼び出すことができます。

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

注: 必要なオーバーロードは 1 つだけであるという jrok の意見に同意しますが、実装 (標準に完全に準拠する必要はない) には別の方向が必要なようです。

于 2013-08-22T19:12:00.027 に答える
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);
于 2013-08-22T18:55:49.680 に答える