bind函数如何在c ++中用于函数对象

Pau*_*ese 6 c++ c++11

我遇到了以下find_if函数.

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

我怀疑如何评估bind(greater(),_ 1,x)和bind(less(),_ 1,y)并在那里返回bool值?这将不起作用,如下所示.

#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
}
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*Mee 5

要理解这一点,我们就需要1 了解bind,结合它的参数.鉴于这g是使用以下bind函数调用的表达式的结果g(u1, u2, ... uM):

  • 如果所存储的参数arg是类型的std::reference_wrapper<T>(例如,std::ref或者std::cref在结合的初始呼叫中使用),则该参数vnstd::invoke上述呼叫是arg.get()和类型Vn在同一呼叫是T&:所存储的参数通过引用传递到被调用的功能对象.
  • 如果所存储的参数arg是类型T为其中std::is_bind_expression<T>::value == true(意思是,另一个结合表达直接通入到结合初始呼叫),然后将其绑定执行功能组成:代替传递函数对象绑定子表达式将返回,子表达式被调用急切地,它的返回值被传递给外部可调用对象.如果绑定子表达式有任何占位参数,它们与外部绑定共享(挑选出来的u1,u2......).具体而言,该参数vnstd::invoke呼叫以上是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,...被用作参数绑定初始呼叫),则该参数由所述占位符(表示u1_1,u2_2等)被传递到可调用对象:参数vnstd::invoke呼叫以上是std::forward<Uj>(uj)和相应的类型Vn以相同的呼叫Uj&&.
  • 否则,普通存储参数arg被传递给可调用对象作为左值参数:参数vnstd::invoke上述呼叫是简单地Arg和相应的类型VnT cv &,其中cv是相同的CV-资格作为的g.

关键在于第二个子弹.因为在绑定时调用绑定表达式,所以这适用:

std::cout << std::bind(std::logical_and<bool>(), fn1, fn2)()
Run Code Online (Sandbox Code Playgroud)

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

std::cout << std::logical_and<bool>()(fn1, fn2)()
Run Code Online (Sandbox Code Playgroud)

  • @PaulVarghese我喜欢`bind`因为它的清晰度以及我在`bind_1st`和`bind_2nd`时代对它的熟悉程度.但老实说,编译器已经改进了`bind`的优化以优化lambdas.至少对于gcc来说是这样的:https://youtu.be/ZlHi8txU4aQ我不确定Visual Studio在哪里可以登陆,但我认为一般的气候说喜欢lambdas来"绑定". (2认同)