5

我有一个看起来像这样的结构,

struct Foo {
    int a;
};

我有一个看起来像这样的结构的向量,

vector<Foo> foos;

所有的Foos 都使用 STL sort() 函数按整数a升序排序。现在我想获取Foo成员字段a小于或等于给定数字的对象,例如 STL lower_bound() 函数。问题是 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)不是 type Foo。我遇到了lower_bound()、upper_bound() 和binary_search() 的问题。custom_comp 只定义了排序,并没有定义 a = 5 的对象实际上等于 int 5。

用 STL 有什么优雅的方法吗?

编辑:

我意识到我的例子并不能完全代表我的问题。我实际上拥有的是 Foo 包含两个整数,a 和 b。当我调用lower_bound 时,我无权访问b(因为我不关心它)。现在 billz 答案的问题是我必须定义一个仅a作为参数的构造函数,这在我看来不是很优雅(因为 b 未定义或任意,并且此构造函数可以在任何地方使用)代码)。但如果这是唯一的选择,我会接受。

4

3 回答 3

1

你可以为你的 struct 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 回答
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 回答
0

让您的 custom_comp 同时接受fooint作为参数。这意味着它要么需要是一个仿函数,要么它可以接受foo_sort_helper参数(可以从 anint或 a构造foo)并对它们进行排序。

或者,明确地说:

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 构造,我允许Fooint无缝比较。

我提到的另一种方法是创建一个在每对Fooand int(全部 4 个)上重载 operator() 的类。我觉得上面的更容易。

如果您要排序的类型复制成本很高(例如std::string),则FooSortHelper可以存储对所述字段的引用。

于 2012-11-13T02:03:03.617 回答