C ++ for_each () и указатель на функцию - PullRequest
0 голосов
/ 28 октября 2010

Я пытаюсь заставить myFunction дать мне сумму значений в массиве, но я знаю, что не могу использовать возвращаемое значение, и когда я запускаю свою программу с кодом, все, что я получаю, это распечатказначений и нет суммы, почему это?

void myFunction (int i) {
int total = 0;
total += i;
cout << total;
}


int main() {
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

for_each( array, array+10, myFunction);


return 0;
}

Ответы [ 8 ]

8 голосов
/ 28 октября 2010

Вам действительно нужен функтор для хранения состояния между итерациями:

struct Sum
{
    Sum(int& v):  value(v) {}
    void operator()(int data) const { value += data;}

    int& value;
};

int main()
{
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    int total = 0;
    std::for_each( array, array+10, Sum(total));

    std::cout << total << std::endl;
}
1 голос
/ 28 октября 2010

total - переменная с автоматической продолжительностью хранения.Каждый раз, когда вызывается myFunction(), создается новый total и инициализируется равным 0. Вы можете:

  • дать total статическую продолжительность хранения (с ключевым словом static), но выне сможет присвоить его значение чему-либо, потому что это все еще локальная область.В любом случае, плохая идея, если вы хотите повторно использовать эту функцию.
  • делает total глобальной переменной.Также плохая идея, если вы хотите повторно использовать эту функцию
  • сделать «функтор», как описано в ответе Мартина Йорка.Это самая многоразовая реализация

Но я выбрал решение "вы задаете неправильный вопрос" и вам следует использовать std::accumulate():

#include <iostream>
#include <numeric>

int main() {
  int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

  int total = std::accumulate(array, array+10, 0);
  std::cout << total << '\n';
  return 0;
}
1 голос
/ 28 октября 2010

Когда вы объявляете переменную (т. Е. int total), она существует в течение срока ее действия (обычно эквивалентна ближайшей окружающей паре { и }. Итак, в вашей функции myFunction, total перестает существовать, когда функция возвращается. Она возвращает один раз за вызов - один раз за элемент в вашем массиве, то есть. Чтобы фактически суммировать его значения (или иным образом сохранить переменную после конца myFunction, вы должны дать это более широкий охват.

Есть два способа сделать это. Один - это «хороший» способ, а другой - «более простой, но плохо стилизованный». Хороший способ - использование функтора или объекта контекста - @ Martin уже опубликовал пример. «Плохой» способ - пометить int total как static. Это сработает при первом использовании, если ваш код однопоточный ... и больше никогда. Если кто-то предлагает это ... не делайте этого . :)

0 голосов
/ 28 октября 2010

Вы сбрасываете значение «total» на 0 каждый раз, когда вызываете функцию.

Объявите это 'static'

void myFunction (int i) {
    static int total = 0;
    total += i;
    cout << total;
}

РЕДАКТИРОВАТЬ:

В качестве альтернативы, если вы хотите получить доступ к значению'total' позже вам нужно будет либо использовать глобальную переменную (какого-то рода! Может быть в классе или функторе! не тратьте меня!), либо просто использовать цикл for и передавать его в качестве указателя (т.е. не используйте for_each):

void myFunction (int i, int * p_total) {
    //No initialization
    *p_total += i;
    cout << *p_total;
}


int main() {
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int total = 0;

    for(int i = 0; i < 10, i++)
       myFunction(array[i], &total);

    //total is now 55

    return 0;
}

Примечание: я программист на C, пытающийся изучать C ++.Вот как я бы это сделал (что очень похоже на C), это может быть не стандартным способом C ++.

0 голосов
/ 28 октября 2010

Вы должны сделать общее постоянным при вызовах функций. Вам также необходимо получить доступ к результату отдельно от добавления к нему промежуточных результатов, что вообще исключает (по крайней мере, прямое использование) функцию - вместо этого вам действительно нужен класс.

0 голосов
/ 28 октября 2010

myFunction вызывается каждый раз, а total является локальным для функции ... попробуйте пометить total как static вместо:

static int total = 0
0 голосов
/ 28 октября 2010

Ваш total является локальным при каждом вызове функции. Он инициализируется с 0 на каждой итерации. Вы можете просто объявить его глобальным (или упаковать в параметр и т. Д.)

0 голосов
/ 28 октября 2010

total является локальной переменной.Он будет уничтожен, как только myFunction закончит обработку данных.

Типичный способ получить состояние - сделать myFunction функциональный объект (структура, перегружающая * 1008).* оператор).
Грязный способ - сделать total глобальной переменной.
В вашем случае я бы рекомендовал использовать функцию accumulate вместо этого (при условии, что cout << totalтолько для отладки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...