std :: bind2nd和std :: bind与二维数组和结构数组
我知道C ++具有lambda和std :: bind1st,std :: bind2nd和std :: bind已被弃用.
I know that C++ have lambdas and std::bind1st, std::bind2nd and std::bind are deprecated.
但是,从C ++的基础开始,我们可以了解更好的新功能.
However, start with the foundations of C++, we can understand better new features.
所以,我从这个非常简单的代码开始,使用一个 int数组:
So, I start with this very simple code, using an array of ints:
第一个示例:使用 std :: bind2nd
int array1[] = { 10, 20, 30, 40, 50, 60, 40 };
int c1, c2, c3;
c1 = count_if(array1, array1 + 7, bind2nd(greater<int>(), 40));
c2 = count_if(array1, array1 + 7, bind2nd(less<int>(), 40));
c3 = count_if(array1, array1 + 7, bind2nd(equal_to<int>(), 40));
cout << "There are " << c1 << " elements that are greater than 40." << endl;
cout << "There are " << c2 << " elements that are lesser than 40." << endl;
cout << "There are " << c3 << " elements that are equal to 40." << endl;
第二个示例:使用 std :: bind
greater<int> big;
less<int> small;
equal_to<int> equal;
c1 = count_if(array1, array1 + 7, bind(big, _1, 40));
c2 = count_if(array1, array1 + 7, bind(small, _1, 40));
c3 = count_if(array1, array1 + 7, bind(equal, _1, 40));
cout << "There are " << c1 << " elements that are greater than 40." << endl;
cout << "There are " << c2 << " elements that are lesser than 40." << endl;
cout << "There are " << c3 << " elements that are equal to 40." << endl;
在两种情况下,输出均为:
In both cases the output is:
There are 2 elements that are greater than 40.
There are 3 elements that are lesser than 40.
There are 2 elements that are equal to 40.
如何对如下所示的双向数组进行相同操作:
(我想对第二个坐标进行相同的操作)
How can I do the same with bidimentional arrays like below:
(I want to made the same operations with the 2nd coordinate)
int array2[7][2] = { { 1, 10 }, { 2, 20 }, { 3, 30 },
{ 4, 40 }, { 5, 50 }, { 6, 60 }, { 4, 40 } };
并带有如下所示的结构体数组:
And with arrays of structs like this:
struct st
{
char c;
int i;
};
st array3[] = { { 'a', 10 }, { 'b', 20 }, { 'c', 30 },
{ 'd', 40 }, { 'e', 50 }, { 'f', 60 }, { 'd', 40 } };
在这种情况下,我想对结构数组中的字段"int"执行相同的操作.
In this case, I want to do the same operations with the field 'int' in the array of structs.
有人可以帮助我吗?
谢谢
bind1st
,bind2nd
及其弟兄在C ++ 11中已弃用,并在C ++ 17中被彻底删除.以防万一你不知道这一点.
bind1st
, bind2nd
and their brethren are deprecated in C++11 and outright removed in C++17. Just in case you didn't know this.
使用bind
,解决方案非常简单,您可以使用以下事实:bind
表达式是可组合的,并且可以使用bind
提取数据成员(为简便起见,省略了placeholders
):>
With bind
, the solution is fairly straightforward, you can use the fact that bind
expressions are composable and that you can use bind
to extract a data member (placeholders
omitted for brevity):
auto gr = count_if(array3, array3 + 7, bind(greater<>{}, bind(&st::i, _1), 40));
auto ls = count_if(array3, array3 + 7, bind(less<>{}, bind(&st::i, _1), 40));
auto eq = count_if(array3, array3 + 7, bind(equal_to<>{}, bind(&st::i, _1), 40));
使用bind2nd
并不是那么容易.您需要声明一个具有多个typedef的函数对象(不能使用函数).您可以使用binary_function
缓解此问题:
With bind2nd
it's not that easy. You need to declare a function object (can't use a function) that has several typedefs. You can use binary_function
to ease this:
struct my_greater : binary_function<st, int, bool>
{
bool operator()(st const& l, int r) const {
return greater<>{}(l.i, r);
}
};
然后您可以致电
auto old = count_if(array3, array3 + 7, bind2nd(my_greater{}, 40));
在C ++ 11中,您可以使用lambda:
In C++11 you cam employ lambdas:
auto XI = count_if(array3, array3 + 7, [](st const& l){ return l.i > 40});
如果您具有C ++ 11或更高版本,则使用lambda几乎总是更好的选择.这不仅是一个很好的默认设置",您还必须真正扭曲这种情况,以使bind
成为更好的解决方案.
If you have C++11 or newer available, it's almost always the better choice to use lambdas. It's not just a "good default", you'd have to really contort the situation for bind
to be a better solution.