16

我有一个foowhich 是一个std::vector<int>. 它表示一组范围的“边缘”值。

例如,如果foo是 {1, 3, 5, 7, 11},则范围是 1-3、3-5、5-7、7-11。对我来说意义重大的是,这相当于 4 个时期。请注意,每个句点都包括范围内的第一个数字,而不是最后一个数字。因此,在我的示例中,8 出现在第三个(从零开始)期间。7 也出现在第 3 期。11及以上不会出现在任何地方。2 出现在第 0 期。

给定 a barwhich is an int,我使用

std::find_if(
    foo.begin(),
    foo.end(),
    std::bind2nd(std::greater<int>(), bar)
) - foo().begin() - 1;

给我应该包含的时期bar

我的问题:std::bind2nd已弃用,所以我应该重构。使用更新函数的等效语句是什么?std::bind不会以明显的方式“加入”。

4

3 回答 3

17

在 C++11 中,您可以使用std::bind; 如何使用它并不那么明显:

#include <functional>
using namespace std::placeholders;
std::find_if(
    foo.begin(),
    foo.end(),
    // create a unary function object that invokes greater<int>::operator()
    // with the single parameter passed as the first argument and `bar` 
    // passed as the second argument
    std::bind(std::greater<int>(), _1, bar)
) - foo().begin() - 1;

关键是使用在std::placeholders命名空间中声明的占位符参数。std::bind返回一个函数对象,该对象在调用时接受一定数量的参数。调用内部使用的占位符std::bind显示调用结果对象时提供的参数如何映射到要绑定的可调用对象的参数列表。因此,例如:

auto op1 = std::bind(std::greater<int>(), _1, bar);
op1(5); // equivalent to std::greater<int>()(5, bar)

auto op2 = std::bind(std::greater<int>(), bar, _1);
op2(5); // equivalent to std::greater<int>()(bar, 5)

auto op3 = std::bind(std::greater<int>(), _2, _1);
op3(5, bar); // equivalent to std::greater<int>()(bar, 5)

auto op4 = std::bind(std::greater<int>(), _1, _2);
op4(5, bar); // equivalent to std::greater<int>()(5, bar)
于 2015-09-23T12:04:07.230 回答
16

bind2nd绕过青铜时代( ),使用 C++14 通用 lambda从石器时代( )直接进入铁器时代bind怎么样?

std::find_if(foo.begin(), foo.end(), [&](auto const& elem) { 
    return elem > bar; 
}); 

如果输入是排序的

std::lower_bound(foo.begin(), foo.end(), bar); 

Lambda 比表达式更容易阅读,也更容易内联std::bind。参见例如Lavevej 的 CppCon 2015演讲。

于 2015-09-23T12:06:29.990 回答
6

bind版本将是:

bind(std::greater<int>(), placeholders::_1, bar)

但我认为,更鼓励使用 lambda,如:

[bar](const int a){return bar < a;}

还鼓励使用重载函数begin/end而不是方法调用。所以它会像:

find_if(begin(foo), end(foo), [bar](const int a){return bar < a;})
于 2015-09-23T12:04:43.873 回答