它们是完全不同的算法:线性find_if
查找谓词为真的第一项,如果给定值在其中,则利用对范围进行排序以对数时间进行测试。binary_search
谓词 forbinary_search
指定对范围进行排序所依据的函数(您很可能希望使用用于对其进行排序的相同谓词)。
您不能利用排序来搜索满足某些完全不相关的谓词的值(find_if
无论如何您都必须使用)。但是请注意,使用排序范围,您可以做的不仅仅是使用lower_bound
,upper_bound
和测试是否存在equal_range
。
这个问题,目的是什么std::binary_function
是一个有趣的问题。
它所做的只是为 和 提供result_type
类型first_argument_type
定义second_argument_type
。这些将允许用户在给定函子作为模板参数的情况下找出并使用这些类型,例如
template <class T, class BinaryFunction>
void foo(const T& a, const T& b, BinaryFunction f)
{
//declare a variable to store the result of the function call
typename BinaryFunction::result_type result = f(a, b);
//...
}
但是,我认为在标准库中使用它们的唯一地方是创建其他仿函数包装器,例如bind1st
, bind2nd
, not1
, not2
。(如果它们被用于其他目的,只要你将函数用作函子,人们就会对你大喊大叫,因为这将是一件不可移植的事情。)
例如,binary_negate
可以实现为 (GCC):
template<typename _Predicate>
class binary_negate
: public binary_function<typename _Predicate::first_argument_type,
typename _Predicate::second_argument_type, bool>
{
protected:
_Predicate _M_pred;
public:
explicit
binary_negate(const _Predicate& __x) : _M_pred(__x) { }
bool
operator()(const typename _Predicate::first_argument_type& __x,
const typename _Predicate::second_argument_type& __y) const
{ return !_M_pred(__x, __y); }
};
当然,operator()
可能只是一个模板,在这种情况下,那些 typedef 是不必要的(有什么缺点吗?)。可能还有元编程技术可以找出参数类型是什么,而无需用户显式地对它们进行类型定义。我想它会在某种程度上妨碍 C++0x 提供的功能 - 例如,当我想使用可变参数模板为任何数量的函数实现否定器时......
(与 和 相比,IMO 的 C++98 仿函数有点过于不灵活和原始std::tr1::bind
,std::tr1::mem_fn
但可能当时编译器对实现这些工作所需的元编程技术的支持并不那么好,也许这些技术仍在被发现。 )