Je sais que C ++ a lambdas et std :: bind1st, std :: bind2nd et std :: bind sont obsolètes.
Cependant, commençons par les bases du C ++, nous pouvons mieux comprendre les nouvelles fonctionnalités.
Donc, je commence avec ce code très simple, en utilisant un tableau d’inters :
Premier exemple: avec 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;
Deuxième exemple: avec 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;
Dans les deux cas, le résultat est:
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.
Comment puis-je faire la même chose avec les tableaux bidimentionnels comme ci-dessous:
(Je veux faire les mêmes opérations avec la 2ème coordonnée)
int array2[7][2] = { { 1, 10 }, { 2, 20 }, { 3, 30 }, { 4, 40 }, { 5, 50 }, { 6, 60 }, { 4, 40 } };
Et avec des tableaux de structures comme ceci:
struct st { char c; int i; }; st array3[] = { { 'a', 10 }, { 'b', 20 }, { 'c', 30 }, { 'd', 40 }, { 'e', 50 }, { 'f', 60 }, { 'd', 40 } };
Dans ce cas, je souhaite effectuer les mêmes opérations avec le champ “int” dans le tableau de structures.
Quelqu’un peut-il m’aider?
Je vous remercie
bind1st
, bind2nd
et leurs frères sont déconseillés en C ++ 11 et carrément supprimés en C ++ 17. Juste au cas où vous ne le saviez pas.
Avec bind
, la solution est assez simple, vous pouvez utiliser le fait que les expressions de bind
sont composables et que vous pouvez utiliser bind
pour extraire un membre de données ( placeholders
omis pour des raisons de brièveté):
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));
Avec bind2nd
ce n’est pas si facile. Vous devez déclarer un object de fonction (ne pouvant utiliser une fonction) comportant plusieurs typedefs. Vous pouvez utiliser binary_function
pour faciliter ceci:
struct my_greater : binary_function { bool operator()(st const& l, int r) const { return greater<>{}(li, r); } };
Ensuite, vous pouvez appeler
auto old = count_if(array3, array3 + 7, bind2nd(my_greater{}, 40));
En C ++ 11, vous utilisez des lambdas:
auto XI = count_if(array3, array3 + 7, [](st const& l){ return li > 40});
démo de tous
Si vous disposez de C ++ 11 ou plus récent, utiliser lambdas est presque toujours le meilleur choix. Ce n’est pas simplement un “bon défaut”, il faudrait vraiment contourner la situation pour que bind
soit une meilleure solution.