绑定函数如何对 C++ 中的函数对象工作

how bind function works for functional objects in c++

本文关键字:函数 对象 工作 绑定 C++      更新时间:2023-10-16

我遇到了以下find_if函数。

find_if (coll.begin(), coll.end(), 
             bind(logical_and<bool>(), 
                  bind(greater<int>(),_1,x), bind(less<int>(),_1,y)
                 )
         );
我怀疑绑定(更大(),_

1,x)和绑定(less(),_1,y)是如何计算并在那里返回布尔值的?否则这将不起作用,如下所示。

#include <iostream>
#include <functional>
int main()
{
    using namespace std::placeholders;
    //auto fn = std::bind(std::greater<int>(), 5, _1);
    //std::cout << fn(7) << std::endl;
    //std::cout << typeid(fn).name() << std::endl;
    auto fn1 = std::bind(std::greater<int>(),5,6);
    auto fn2 = std::bind(std::less<int>(),7,5);
    std::cout << std::bind( std::logical_and<bool>(), fn1, fn2 )(); // how this works??
    std::cout << std::logical_and<bool>()(fn1, fn2)();  // Compilation error
}

真的很想知道函子是如何在绑定函数中调用的。有人可以解释一下这是如何工作的吗?提前谢谢。

要理解这一点,我们需要 1st 了解 bind 如何绑定它的参数。鉴于gbind表达式的结果,该表达式调用如下: g(u1, u2, ... uM)

  • 如果存储的参数 arg 是 std::reference_wrapper<T> 类型(例如,在初始调用 bind 中使用了 std::refstd::cref),则arg.get()上述std::invoke调用中的参数vn,同一调用中的Vn类型T&:存储的参数通过引用传递到调用的函数对象中。
  • 如果存储的参数 arg 属于std::is_bind_expression<T>::value == trueT 类型(这意味着,另一个绑定表达式直接传递到对绑定的初始调用中),则 bind 执行函数组合:不是传递绑定子表达式将返回的函数对象,而是急切地调用子表达式,并将其返回值传递给外部可调用对象。如果绑定子表达式有任何占位符参数,则它们与外部绑定共享(从u1u2、...中选取)。具体来说,上面std::invoke调用中vn的参数是arg(std::forward<Uj>(uj)...)的,同一调用中的Vn类型是std::result_of_t<T cv &(Uj&&...)>&&的(cv 限定条件与 g 的相同)。
  • 如果存储的参数 arg 是类型 T ,则std::is_placeholder<T>::value != 0 ,这意味着占位符,例如 std::placeholders::_1_2_3、...用作初始调用 bind 的参数),然后将占位符指示的参数(u1 表示 _1u2 表示_2等)传递给可调用对象:上面 std::invoke 调用中vn的参数是std::forward<Uj>(uj),同一调用中的相应类型VnUj&&
  • 否则,普通存储的参数 arg 将作为 lvalue 参数传递给可调用对象:上面 std::invoke 调用中vn的参数只是 arg,对应的类型VnT cv & ,其中 cvg 的 cv 限定符相同。

关键在第二个项目符号中。由于绑定表达式是在绑定时调用的,因此可以正常工作:

std::cout << std::bind(std::logical_and<bool>(), fn1, fn2)()

但由于没有为绑定表达式定义&运算符,因此这不起作用:

std::cout << std::logical_and<bool>()(fn1, fn2)()