如何std :: find使用Compare对象? [英] How to std::find using a Compare object?

查看:159
本文介绍了如何std :: find使用Compare对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 std :: find 的界面感到困惑。为什么不需要一个比较对象来告诉它如何比较两个对象?



如果我可以传递一个比较对象,我可以使以下代码工作,我想比较值,而不是直接比较指针值:

  typedef std :: vector< std :: string *> Vec; 
Vec vec;
std :: string * s1 = new std :: string(foo);
std :: string * s2 = new std :: string(foo);
vec.push_back(s1);
Vec :: const_iterator found = std :: find(vec.begin(),vec.end(),s2);
//找不到,显然,因为我不能告诉它比较值
delete s1;
delete s2;以下是推荐的方法?









$ b

 模板< class T> 
struct MyEqualsByVal {
const T& X_;
MyEqualsByVal(const T& x):x_(x){}
bool operator()(const T& y)const {
return * x_ == * y;
}
};
// ...
vec.push_back(s1);
Vec :: const_iterator found =
std :: find_if(vec.begin(),vec.end(),
MyEqualsByVal< std :: string *>(s2) // OK,will findfoo


解决方案

find 不能重载为使用一元谓词而不是值,因为它是一个不受约束的模板参数。因此,如果你调用 find(first,last,my_predicate),那么无论你想要对范围的每个成员求值谓词还是一个潜在的不确定性,想要找到一个等于谓词本身的范围的成员(它可以是一系列谓词,对于所有标准库的设计者都知道或关心,或 value_type 可以转换为谓词类型和它的 argument_type )。因此,需要 find_if 以一个单独的名称。



find 可能已被重载以获取可选的二进制谓词,除了搜索的值。但是像你做的那样捕获函数中的值是一个标准的技术,我不认为这是一个巨大的收益:它肯定没有必要,因为你总是可以实现相同的结果 find_if



如果你需要找到,你还是必须写一个函子,因为< functional> 不包含任何用于解引用指针的引用。你的函数会比一个二元谓词更简单,或者你可以使用一个函数指针,所以它是一个适度的增益。所以我不知道为什么这不是提供。给定 copy_if fiasco我不确定有很多的价值,假设总是有很好的理由的算法不可用: - )


I am confused about the interface of std::find. Why doesn't it take a Compare object that tells it how to compare two objects?

If I could pass a Compare object I could make the following code work, where I would like to compare by value, instead of just comparing the pointer values directly:

typedef std::vector<std::string*> Vec;
Vec vec;
std::string* s1 = new std::string("foo");
std::string* s2 = new std::string("foo");
vec.push_back(s1);
Vec::const_iterator found = std::find(vec.begin(), vec.end(), s2);
// not found, obviously, because I can't tell it to compare by value
delete s1;
delete s2;

Is the following the recommended way to do it?

template<class T>
struct MyEqualsByVal {
  const T& x_;
  MyEqualsByVal(const T& x) : x_(x) {}
  bool operator()(const T& y) const {
    return *x_ == *y;
  }
};
// ...
vec.push_back(s1);
Vec::const_iterator found = 
    std::find_if(vec.begin(), vec.end(),
                 MyEqualsByVal<std::string*>(s2)); // OK, will find "foo"

解决方案

find can't be overloaded to take a unary predicate instead of a value, because it's an unconstrained template parameter. So if you called find(first, last, my_predicate), there would be a potential ambiguity whether you want the predicate to be evaluated on each member of the range, or whether you want to find a member of the range that's equal to the predicate itself (it could be a range of predicates, for all the designers of the standard libraries know or care, or the value_type of the iterator could be convertible both to the predicate type, and to its argument_type). Hence the need for find_if to go under a separate name.

find could have been overloaded to take an optional binary predicate, in addition to the value searched for. But capturing values in functors, as you've done, is such a standard technique that I don't think it would be a massive gain: it's certainly never necessary since you can always achieve the same result with find_if.

If you got the find you wanted, you'd still have to write a functor (or use boost), since <functional> doesn't contain anything to dereference a pointer. Your functor would be a little simpler as a binary predicate, though, or you could use a function pointer, so it'd be a modest gain. So I don't know why this isn't provided. Given the copy_if fiasco I'm not sure there's much value in assuming there are always good reasons for algorithms that aren't available :-)

这篇关于如何std :: find使用Compare对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆