具有不同类型的stl谓词

时间:2010-08-20 16:27:45

标签: c++ stl

我有一个有序容器类的向量,我需要知道具有给定元素的容器的索引

所以,我想做以下几点,但这显然不起作用。我可以创建一个虚拟容器来容纳要查找的日期,但我想知道是否有更好的方法。

struct FooAccDateComp 
{
  bool operator()(const Container& d1, const MyDate&  f1) const 
  { return   d1->myDate < f1; } 
};

class Container
{
   MyDate myDate;
   ...
};

vector<Container> mystuff; 
MyDate temp(2008, 3, 15);

//add stuff to variable mystuff

int index = int(upper_bound(events.begin(), events.end(),temp, FooAccDateComp())-events.begin());

编辑:容器类可以包含其他日期。

4 个答案:

答案 0 :(得分:4)

upper_bound需要能够评估Comp(date,container)等表达式,但您只提供了Comp(container,date)。您需要同时提供:

struct FooAccDateComp 
{
    bool operator()(const Container& c, const MyDate& d) const 
        { return c.myDate < d; } 

    bool operator()(const MyDate& d, const Container& c) const 
        { return d < c.myDate; } 
};

请记住,必须根据upper_bound和朋友的比较对矢量进行排序。

答案 1 :(得分:1)

您不一定需要特殊谓词,只需启用Container和MyDate之间的比较。

#include <vector>

struct MyDate {
   MyDate(int, int, int);
};

struct Container {
   MyDate myDate;
};

// enable comparison between Container and MyDate
bool operator<(Container const&, MyDate const&);
bool operator==(Container const&, MyDate const&);

std::vector<Container> v; 
//add stuff to variable mystuff
MyDate temp(2008, 3, 15);
std::vector<Container>::iterator i = std::lower_bound(v.begin(), v.end(), temp);
ptrdiff_t index = i != v.end() && *i == temp ? i - v.begin() : -1;

答案 2 :(得分:0)

如果你不介意降低性能,可以使用find_if(你说你有一个排序Container的向量,所以二进制搜索会更快) 或者你可以添加

struct Container {
    MyDate myDate;
    operator MyDate () {return myDate}; 
}
bool operator <(MyDate  const&, MyDate const&)
{
  return // your logic here
};    

现在您可以使用二进制搜索功能

std::vector<Container>::iterator i = std::upper_bound(v.begin(), v.end(), MyDateObject);

当然,只有当您的矢量按Container.myDate

排序时,它才会起作用

答案 3 :(得分:0)

您的示例以几种微不足道的方式被破坏:类Container应该在FooAccDateComp之前定义,以便在那里使用它,您应该myDate一个公开<{em>} Container成员,使用.myDate而不是->myDate访问比较方法中的该成员,最后决定是否调用向量mystuff或{{1但是不要混合两者。我认为已经进行了适当的更正。

您应该定义比较函数,将events参数作为第一个参数,将Date参数作为第二个参数;与你所做的相反。或者你可以使用Container而不是std::lower_bound,如果这符合你的目的(因为你不能说你要用std::upper_bound做什么,这很难说)问题中的选择是适应的。与目前接受的答案相反,如果您仅使用index或仅使用std::upper_bound,则不需要两者(尽管如果使用std::lower_bound则需要两者,或者同时使用std::equal_range。 1}}和std::upper_bound)。

你可以在标准中看到这些乍一看有点奇怪的规格,但有一种方法可以理解而不用查找为什么它们必须像这样。使用std::lower_bound时,您希望找到将lower_bound条目(严格地)小于给定Container的条目与不区分的条目分开的点,这需要调用比较函数将Date参数放在第二位。但是,如果您要求Date(按原样),您希望找到将严格更大的条目与您给定的upper_bound分开的点。是,这需要在第一个位置调用带有Date参数的比较函数(并且否定它返回的布尔结果)。对于Date,你当然需要两种可能性。