std :: bind2nd y std :: bind con matrices bidimensionales y matrices de estructuras

Sé que C ++ tiene lambdas y std :: bind1st, std :: bind2nd y std :: bind están en desuso.

Sin embargo, comience con los fundamentos de C ++, podemos entender mejores características nuevas.

Entonces, empiezo con este código muy simple, usando una matriz de int s:

Primer ejemplo: con std :: bind2nd

int array1[] = { 10, 20, 30, 40, 50, 60, 40 }; int c1, c2, c3; c1 = count_if(array1, array1 + 7, bind2nd(greater(), 40)); c2 = count_if(array1, array1 + 7, bind2nd(less(), 40)); c3 = count_if(array1, array1 + 7, bind2nd(equal_to(), 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; 

Segundo ejemplo: con std :: bind

 greater big; less small; equal_to 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; 

En ambos casos la salida es:

 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. 

¿Cómo puedo hacer lo mismo con las matrices bidimensionales como a continuación:
(Quiero hacer las mismas operaciones con la 2da coordenada)

 int array2[7][2] = { { 1, 10 }, { 2, 20 }, { 3, 30 }, { 4, 40 }, { 5, 50 }, { 6, 60 }, { 4, 40 } }; 

Y con matrices de estructuras como esta:

 struct st { char c; int i; }; st array3[] = { { 'a', 10 }, { 'b', 20 }, { 'c', 30 }, { 'd', 40 }, { 'e', 50 }, { 'f', 60 }, { 'd', 40 } }; 

En este caso, quiero hacer las mismas operaciones con el campo ‘int’ en la matriz de estructuras.

¿Alguien puede ayudarme?

Gracias

bind1st , bind2nd y sus hermanos están en desuso en C ++ 11 y se eliminan totalmente en C ++ 17. Por si acaso no sabías esto.

Con el bind , la solución es bastante sencilla, puede usar el hecho de que las expresiones de bind son compostables y puede usar el bind para extraer un miembro de datos (los placeholders omiten por brevedad):

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

Con bind2nd no es tan fácil. Debe declarar un objeto de función (no se puede usar una función) que tenga varias definiciones de tipo. Puedes usar binary_function para facilitar esto:

 struct my_greater : binary_function { bool operator()(st const& l, int r) const { return greater<>{}(li, r); } }; 

Entonces puedes llamar

 auto old = count_if(array3, array3 + 7, bind2nd(my_greater{}, 40)); 

En C ++ 11 cam usas lambdas:

 auto XI = count_if(array3, array3 + 7, [](st const& l){ return li > 40}); 

demo de todos


Si tiene C ++ 11 o una versión más reciente, casi siempre es la mejor opción para usar lambdas. No es solo un “buen valor por defecto”, tendrías que enfrentar realmente la situación para que el bind sea ​​una mejor solución.