简体   繁体   English

std::bind2nd 的替代品

[英]A replacement for std::bind2nd

I have a foo which is a std::vector<int> .我有一个foo ,它是一个std::vector<int> It represents the "edge" values for a set of ranges.它表示一组范围的“边缘”值。

For example, if foo is {1, 3, 5, 7, 11} then the ranges are 1-3, 3-5, 5-7, 7-11.例如,如果foo是 {1, 3, 5, 7, 11} 那么范围是 1-3, 3-5, 5-7, 7-11。 Significantly for me, this equates to 4 periods.对我来说意义重大的是,这相当于 4 个时期。 Note that each period includes the first number in a range, and not the last one.请注意,每个期间都包含一个范围内的第一个数字,而不是最后一个。 So in my example, 8 appears in the 3rd (zero-based) period.所以在我的例子中,8 出现在第三个(从零开始)时期。 7 also appears in the 3rd period. 7也出现在第三期。 11 and above doesn't appear anywhere. 11 及以上不会出现在任何地方。 2 appears in the 0th period. 2 出现在第 0 期。

Given a bar which is an int , I use给定一个bar这是一个int ,我使用

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

to give me the period that should contain bar .给我应该包含bar的句点。

My problem: std::bind2nd is deprecated so I ought to refactor.我的问题: std::bind2nd已被弃用,所以我应该重构。 What is the equivalent statement using updated functions?使用更新函数的等效语句是什么? std::bind doesn't "drop in" in the obvious way. std::bind不会以明显的方式“插入”。

In C++11, you can use std::bind ;在 C++11 中,您可以使用std::bind it just isn't as obvious how to use it:如何使用它并不那么明显:

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

The key is the use of the placeholder argument, which are declared in the std::placeholders namespace.关键是使用占位符参数,它在std::placeholders命名空间中声明。 std::bind returns a function object that takes some number of parameters when it is invoked. std::bind返回一个函数对象,该对象在调用时带有一些参数。 The placeholders used inside the call to std::bind show how the arguments provided when the resulting object is invoked map to the argument list to the callable that you're binding to.在对std::bind的调用中使用的占位符显示调用结果对象时提供的参数如何映射到参数列表到您要绑定到的可调用对象。 So, for instance:因此,例如:

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)

What about going straight from Stone Age ( bind2nd ) to the Iron Age with a C++14 generic lambda, bypassing the Bronze Age ( bind )?使用 C++14 泛型 lambda 直接从石器时代 ( bind2nd ) 进入铁器时代,绕过青铜时代 ( bind ) 怎么样?

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

And if the input is sorted如果输入已排序

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

Lambdas read much easier and are also easier to inline than std::bind expresions. Lambda 比std::bind表达式更容易阅读,也更容易内联。 See eg Lavevej's CppCon 2015 talk.参见例如Lavevej 的 CppCon 2015演讲。

bind version would be: bind版本将是:

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

but I think, it is more encouraged to use lambdas, as in:但我认为,更鼓励使用 lambda,例如:

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

It is also encouraged to use overloaded functions begin/end instead of method calls.还鼓励使用重载函数begin/end而不是方法调用。 so it would be like:所以它会像:

find_if(begin(foo), end(foo), [bar](const int a){return bar < a;})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM