5

std::lower_bound() および std::upper_bound() 構文 (まあ、実際には型変換) で矛盾しているように見えるものを見たので、誰かが解明できるかどうか疑問に思っていましたか? コメントによると、2 行目は 1 行目と明らかに類似しているにもかかわらず、コンパイルされません。3行目に示されているフォームを使用する必要があります(少なくともgcc 4.7.3 / ubuntu 64ビットでは-これですべてです)

#include <set>
#include <algorithm>

using namespace std;

class MyInt {
  private:
    int val;
  public:
    MyInt(int _val): val(_val) {}
    bool operator<(const MyInt& other) const {return val < other.val;}
};

int main() {
    set<MyInt> s;
    s.insert(1);  // demonstrate implicit conversion works
    s.insert(MyInt(2));
    s.insert(3); // one last one for the road
    set<MyInt>::iterator itL = lower_bound(s.begin(), s.end(), 2); //LINE 1
    // the line below will NOT compile
    set<MyInt>::iterator itU = upper_bound(s.begin(), s.end(), 2); //LINE 2
    // the line below WILL compile
    set<MyInt>::iterator itU2 = upper_bound(s.begin(), s.end(), MyInt(2)); // LINE 3
    return 0;
}
4

1 に答える 1

5

バグではないと思います。の(可能な)実装をstd::upper_bound見ると、比較は次のように行われます

if (!(value < *it)) { ... } // upper_bound, implicit conversion `MyInt`->`int` doesn't work

また、は(クラス型ではないoperator<のメンバー関数ではなく) のメンバー関数であるため、 からへの変換がないため、コードはコンパイルされません。一方、 inは比較の左側に表示され、(型の) はに渡されるときに暗黙的に に変換できます。MyIntintMyIntintstd::lower_bound*itvalueintMyIntMyInt::operator<

if (*it < value) { ... } // lower_bound, implicit conversion `int`->`MyInt` works

これが、比較演算子を非メンバーとして実装する方が良い理由であり、この非対称性はありません。これは、Scott Meyers の効果的な C++の本にも記載されています: Item 24: Declare non-member functions when type conversions should apply to all parameters

MyInt::operator int(){return val;}簡単で汚い修正: for の暗黙的な変換MyIntを定義するint. (編集:実際には機能しません、あいまいさ)。機能するのは、暗黙的な変換の必要性を取り除くことです

set<MyInt>::iterator itU = upper_bound(s.begin(), s.end(), MyInt(2));

代わりは。

于 2015-11-09T03:18:55.133 に答える