5

私はこのような構造体を持っています、

struct Foo {
    int a;
};

このような構造体のベクトルがあります。

vector<Foo> foos;

すべての は、STL の sort() 関数を使用しFooて、整数aで昇順にソートされます。ここで、STL の lower_bound() 関数のように、特定の数値以下Fooのメンバー フィールドを持つオブジェクトを取得したいと考えています。a問題は、STL の lower_bound 関数宣言が次のようになっていることです。

template <class ForwardIterator, class T, class Compare>
  ForwardIterator lower_bound ( ForwardIterator first, ForwardIterator last,
                                const T& value, Compare comp );

だから私は何かをしたいのですが、

lower_bound(foos.begin(), foos.end(), 5, custom_comp);

探している int (この場合は 5) がタイプではないため、できませんFoo。この問題は、lower_bound()、upper_bound()、および binary_search() で発生しています。custom_comp は順序付けのみを定義し、a = 5 のオブジェクトが実際に int 5 に等しいことを定義しません。

STLでこれを行うエレガントな方法はありますか?

編集:

私の例が私の問題を完全に表しているわけではないことに気付きました。私が実際に持っているのは、Foo には a と b の 2 つの int が含まれているということです。lower_bound を呼び出すと、b にアクセスできません (気にしないため)。billz の回答の問題はa、パラメーターとしてのみ受け取るコンストラクターを定義する必要があることです。これは、私の意見ではあまりエレガントではありません (b は未定義または任意のままであり、このコンストラクターはコード)。しかし、これが唯一の選択肢である場合、私はそれを取ります。

4

3 に答える 3

1

C ++ 11では、次を使用できます。

std::lower_bound(foos.begin(), foos.end(), Foo{5},
    [](const Foo& f1, const Foo& f2) { return f1.a < f2.a; });

またはC++03の場合:

Foo f = {5};
std::lower_bound(foos.begin(), foos.end(), f, custom_comp);
于 2012-11-13T02:03:10.800 に答える
1

構造体 Foo にコンストラクターを提供できます

struct Foo {
  Foo(int x):a(x){
  }
    int a;
};

あなたは今呼び出すことができます:

std::lower_bound(foos.begin(), foos.end(), 5, custom_comp);

また

std::lower_bound(foos.begin(), foos.end(), Foo(5), custom_comp);

また

Foo f(5);
std::lower_bound(foos.begin(), foos.end(), f, custom_comp);

推奨される方法は次のとおりです。

struct Foo {
  explicit Foo(int x):a(x){
  }
    int a;
};

std::lower_bound(foos.begin(), foos.end(), Foo(5), custom_comp);
于 2012-11-13T01:55:17.417 に答える
0

custom_compにとの両方を引数として受け入れさせfooますint。これは、ファンクターである必要があるか、引数(またはから構築できます)を取り、それらを順序付けることができることを意味しfoo_sort_helperます。intfoo

または、明示的に:

struct FooSortHelper
{
  int ordering;
  FooSortHelper( Foo const& foo ):ordering(foo.value) {}
  FooSortHelper( int i ): ordering(i) {}
  FooSortHelper( FooSortHelper const& other):ordering(other.ordering) {}
  bool operator<( FooSortHelper const& other ) { return ordering < other.ordering }
};

auto lower = std::lower_bound( vec.begin(), vec.end(), 5,
  []( FooSortHelper left, FooSortHelper right ) {
    return left < right;
  }
);

?でどのようにFooソートされているかをカプセル化する方法がわかります。FooSortHelperそして、それをintから構築できるようにすることで、見た目Fooと比較することができintます。

Foo私が言及した別の方法は、 and int(4つすべて)の各ペアでoperator()がオーバーロードされたクラスを作成することです。上記の方が簡単だと思います。

並べ替えるタイプ(などstd::string)のコピーにコストがかかる場合はFooSortHelper、上記のフィールドへの参照を保存できます。

于 2012-11-13T02:03:03.617 に答える