为什么以及如何在 C++ 中使用 bind() 作为谓词?

why and how to use bind() as predicate in c++?

本文关键字:bind 谓词 C++ 为什么      更新时间:2023-10-16

我得到了这个看起来很奇怪的std::generate()函数,它在a和b之间创建了一个随机数std::vector

int myrand(int a, int b)
{
    int div = b-a;
    return a + (rand() % (b-a));
}
int main()
{
    vector<int> v(20);
    generate( v.begin(), v.end(), bind(myrand,1, 11) );  //fill with random no. bwt 1 and 10 
    return 0;
}

我知道std::generate()函数是如何工作的,必须将谓词传递到第三个参数中。谓词可以采用以下形式:

  • 功能
  • 函数对象
  • 函数指针。

但是我对表达bind(myrand,1, 11)感到困惑,为什么我们必须这样写呢?

我知道bind返回一个函数,可以作为这里的第三个参数。

但是,myrand不也是一个函数吗?我试图用myrand(1,11)替换第三个参数,但它不起作用,为什么会这样?

std::bind 接受一个函数对象,以及要传递给函数对象的事物,并返回一个函数对象,该对象将使用这些参数调用提供的函数对象。 这意味着

auto foo = bind(myrand,1, 11);
foo();

myrand(1, 11);

不过,为了让生活更轻松,您可以避免bind而只使用 lambda。 这样做会给你

generate( v.begin(), v.end(), [](){ return myrand(1, 11); });

而且,至少对我来说,这更清楚的是,您得到的是一个对象,每次您调用它时都会返回myrand(1, 11) operator()

std::bind不返回函数,它返回一个带有函数调用运算符的对象,operator()实现。该对象是一个函子对象,可以像函数一样调用。

使用 myrand(1, 11) 时,调用函数myrand并将int结果传递给std::generate 。这个int值不能像函数一样"调用"。

为什么...使用 bind((

通常建议使用 lambda 而不是 std::bindstd::bind用于将参数绑定到函数。 使用 std::bind 会导致函数对象具有比原始函数更小的函数调用运算符。

如何使用 bind((

在你的问题中有一个如何使用 bind(( 的例子。

必须将谓词传递到第三个参数中

实际上,第三个参数是一个生成器。

但是,迈兰德不也是一个函数吗?

是的。

我试图用 myrand(1,11( 替换第三个参数,但它不起作用,为什么会这样?

myrand(1,11)不是函数(也不是函数对象(。这是一个函数调用。结果是int. int不是一个函数。您正在尝试将整数作为可调用对象传递,这不起作用。

Bind 返回一个可调用对象。当你绑定myrand的两个参数时,生成的调用包将不带任何参数。它可以被称为

std::bind(myrand,1,11)();

当您尝试通过myrand(1,11)时,这不是可调用的,而是int

但我

对表达bind(myrand,1, 11)感到非常困惑,为什么我们 非要这样写?

我知道bind返回一个可以作为第三个的函数 在这里争论。

但是,myrand不也是一个函数吗?我试图替换第三个 与myrand(1,11)争论是行不通的,为什么会这样?

myrand是一个函数。 myrand(1,11)是一个int

bind接受一个函数和一些参数,并返回一个类似函数的对象。

generate想要一个类似功能的东西,而不是一个int