C ++ for_each()和函数指针

时间:2010-10-28 17:44:34

标签: c++ function-pointers

我试着让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 个答案:

答案 0 :(得分:8)

你真的需要一个仿函数来在迭代之间存储状态:

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 :(得分:1)

当你声明一个变量(即int total)时,它在其范围的持续时间内存在(通常等同于最近的{}对。所以,在你的函数中myFunctiontotal在函数返回时不再存在。每次调用返回一次 - 数组中每个元素一次,即为了实际求和其值(或以其他方式保留变量)在myFunction结束时,你必须给它更广泛的范围。

有两种相关的方法可以做到这一点。一种是“好”的方式,一种是“更容易但风格很差”的方式。好方法涉及一个仿函数或上下文对象 - @ Martin已经发布了一个例子。 “糟糕”的方式是将int total标记为static。如果您的代码是单线程的话,它将在您第一次使用它时工作......然后再也不会。如果有人建议...... 不要这样做 。 :)

答案 2 :(得分:1)

total是具有自动存储持续时间的变量。每次调用myFunction()时,都会创建一个新的total并将其初始化为0.您可以:

  • 提供total静态存储持续时间(使用static关键字),但您无法将其值分配给任何内容,因为它仍然是本地范围。无论如何,如果你想重用这个功能,这是一个坏主意。
  • 使total成为全局变量。如果你想重用这个功能也是一个坏主意
  • 制作一个“仿函数”,如Martin York的回答所述。这是最可重用的实现

但是,我选择的解决方案是“你问的是错误的问题”,你应该使用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;
}

答案 3 :(得分:0)

total是一个局部变量。一旦myFunction处理完一个数据,它就会被销毁。

拥有状态的典型方法是使myFunction成为function object(一个重载()运算符的结构)。
肮脏的方法是使total成为一个全局变量 在您的情况下,我建议您使用the accumulate function代替(假设cout << total仅用于调试)。

答案 4 :(得分:0)

您的total在每个函数调用中都是本地的。它在每次迭代时都被初始化为0。你可以将它声明为全局(或打包成参数等)

答案 5 :(得分:0)

每次都会调用

myFunction,而total是函数的本地版...尝试将total标记为static

static int total = 0

答案 6 :(得分:0)

您需要在函数调用之间建立总持久性。您还需要单独访问结果,将中间结果添加到结果中,从而排除(至少直接使用)函数 - 您确实需要一个类。

答案 7 :(得分:0)

每次调用该函数时,都会将'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 ++方式。