如何在c ++中的函数对象的绑定函数 [英] how bind function works for functional objects in c++

查看:110
本文介绍了如何在c ++中的函数对象的绑定函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了以下find_if函数。

I came across the following find_if function.

find_if (coll.begin(), coll.end(), 
             bind(logical_and<bool>(), 
                  bind(greater<int>(),_1,x), bind(less<int>(),_1,y)
                 )
         );



我不知道bind(greater(),_ 1,x)和bind less(),_ 1,y)和返回bool值有?这将无法正常工作,如下所示。

I've the doubt that how the bind(greater(),_1,x) and bind(less(),_1,y) are evaluated and returning bool values there? This will not work otherwise as shown below.

#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
}

真的很好奇知道如何在绑定功能。有人可以解释一下如何工作吗?提前感谢。

Really curious to know how the functors are called inside the bind function. Can someone please explain how this works? Thanks in advance.

推荐答案

要了解这一点,我们需要1 st href =http://en.cppreference.com/w/cpp/utility/functional/bind#Member_function_operator.28.29 =nofollow> bind ,绑定它的参数。假设 g 是调用的 bind 表达式的结果: g(u1 ,u2,... uM)

To understand this we'll need to 1st understand how bind, binds it's arguments. Given that g is the result of a bind expression which is called with: g(u1, u2, ... uM):



  • std :: reference_wrapper< T> 类型(例如, std :: ref std :: cref 用于初始调用bind),然后在 std ::中的参数 vn 在同一个调用中调用上面的调用 arg.get()和类型 Vn T& :存储的参数通过引用传递到调用的函数对象。

  • 如果存储的参数arg的类型为 T ,其中 std :: is_bind_expression< T> :: value == true 到绑定的初始调用),然后绑定执行函数组合:而不是传递绑定子表达式将返回的函数对象,子表达式被热切地调用,并且其返回值被传递到外部可调用对象。 strong>如果绑定子表达式有任何占位符参数,它们将与外部绑定(选择 u1 u2 ,...)。具体来说,上面 std :: invoke 调用中的参数 vn arg(std: :forward< Uj(uj)...),并且在同一调用中的类型 Vn std :: result_of_t< T cv&(Uj& ...)>&&< / code>(cv限定条件与 g c> c> std :: is_placeholder< T> :: value!= 0 ,意味着一个占位符,例如 std :: placeholders :: _ 1 _2 _3 ,...用作初始调用的参数bind),然后由占位符指示的参数( $ <$ c> u1 / code>,etc)传递给invokable对象: std :: invoke vn >上面的调用是 std :: forward< Uj>(uj),并且相同类型 Vn Uj&&&

  • 否则,普通存储的参数arg作为lvalue参数传递给invokable对象:上面的 std :: invoke 调用中的c $ c> vn 只是arg和相应的类型 Vn T cv& ,其中 cv 是与 g

  • If the stored argument arg is of type std::reference_wrapper<T> (for example, std::ref or std::cref was used in the initial call to bind), then the argument vn in the std::invoke call above is arg.get() and the type Vn in the same call is T&: the stored argument is passed by reference into the invoked function object.
  • If the stored argument arg is of type T for which std::is_bind_expression<T>::value == true (meaning, another bind expression was passed directly into the initial call to bind), then bind performs function composition: instead of passing the function object that the bind subexpression would return, the subexpression is invoked eagerly, and its return value is passed to the outer invokable object. If the bind subexpression has any placeholder arguments, they are shared with the outer bind (picked out of u1, u2, ...). Specifically, the argument vn in the std::invoke call above is arg(std::forward<Uj>(uj)...) and the type Vn in the same call is std::result_of_t<T cv &(Uj&&...)>&& (cv qualification is the same as that of g).
  • If the stored argument arg is of type T, for which std::is_placeholder<T>::value != 0, meaning, a placeholder such as std::placeholders::_1, _2, _3, ... was used as the argument to the initial call to bind), then the argument indicated by the placeholder (u1 for _1, u2 for _2, etc) is passed to the invokable object: the argument vn in the std::invoke call above is std::forward<Uj>(uj) and the corresponding type Vn in the same call is Uj&&.
  • Otherwise, the ordinary stored argument arg is passed to the invokable object as lvalue argument: the argument vn in the std::invoke call above is simply arg and the corresponding type Vn is T cv &, where cv is the same cv-qualification as that of g.

键位于2 < sup> nd 。因为绑定表达式在绑定时被调用,所以这是有效的:

The key is in the 2nd bullet. Because the bind expressions are invoked at binding time this works:

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

但是因为没有为绑定表达式定义& 运算符,所以这将不起作用:

But because there is no & operator defined for bind expressions, this won't work:

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

这篇关于如何在c ++中的函数对象的绑定函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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