std :: bind2nd и std :: bind с двумерными массивами и массивами структур

Я знаю, что в C ++ есть лямбды и std :: bind1st, std :: bind2nd и std :: bind устарели.

Однако, начав с основ C ++, мы сможем лучше понять новые функции.

Итак, я начну с этого очень простого кода, используя массив ints:

Первый пример: с станд :: 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;

Второй пример: с станд :: привязывать

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;

В обоих случаях вывод:

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.

Как я могу сделать то же самое с двумерными массивами, как показано ниже:
(Я хочу сделать те же операции со 2-й координатой)

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

И с массивами структур, как это:

struct st
{
char c;
int i;
};

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

В этом случае я хочу выполнить те же операции с полем ‘int’ в массиве структур.

Может кто-нибудь мне помочь?

Спасибо

3

Решение

bind1st, bind2nd и их братья устарели в C ++ 11 и полностью удалены в C ++ 17. На всякий случай, если вы этого не знали.

С bindрешение довольно простое, вы можете использовать тот факт, что bind выражения составляются и что вы можете использовать bind извлечь элемент данных (placeholders опущено для краткости):

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 чтобы облегчить это:

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 вы можете использовать лямбды:

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

демо всего


Если у вас есть C ++ 11 или новее, почти всегда лучше использовать лямбды. Это не просто «хороший дефолт», вам придется реально исказить ситуацию для bind быть лучшим решением.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]