C++函数对象无法使用std :: for_each(VS2012)创建总和

bas*_*h.d 2 c++ foreach stl function-object visual-studio

我在Visual Studio 2012中使用函数对象时遇到问题.

我创建了一个简单的std::vector,添加了ints0-9并希望使用函数对象创建它的总和.我的班级定义(内联):

template <class T>
class Sum {
private:
    T val;
public:
    Sum (T i = 0) : val(i) {
    }

    void operator()(T x) { 
        val += x; 
    }

    T result() const { 
        return val; 
    }

    ~Sum() {
        std::cout << "Invoked destructor! val: " << val << " for this: " << this << std::endl;
    }
};
Run Code Online (Sandbox Code Playgroud)

我的主要功能:

int main(int argc, char *argv[]){

    Sum<int> s;

    int contents[] = {1,2,3,4,5,6,7,8,9};

    std::vector<int> vec = std::vector<int>(contents, contents + 9);

    std::for_each(vec.begin(), vec.end(), s);

    std::cout << "Sum of all numbers: " << s.result() << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用析构函数的输出,我将得到:

Invoked destructor! val: 45 for this: 003BFDA4
Invoked destructor! val: 45 for this: 003BFDE0
Sum of all numbers: 0
Invoked destructor! val: 0 for this: 003BFEFC
Run Code Online (Sandbox Code Playgroud)

这是VS的错误吗?使用调试器运行它,项目总结为45但之后立即调用析构函数.我究竟做错了什么?

编辑:

这是Stroustrup的The C++ Programming Language第18.4章的一个例子.我只是想知道它不起作用,因为我完全复制了它.

And*_*owl 5

问题是按值std::for_each接受您的仿函数参数.这意味着它可以处理原始对象的副本.好消息是它还返回保存修改状态的副本.这应该做的伎俩:

Sum<int> s1 = std::for_each(vec.begin(), vec.end(), s);
std::cout << "Sum of all numbers: " << s1.result() << std::endl;
Run Code Online (Sandbox Code Playgroud)

或者,您可以让val您的仿函数成为某个变量的引用:

template <class T>
class Sum {
private:
    T& val;
public:
    Sum (T& i) : val(i) {
    }
// ...
Run Code Online (Sandbox Code Playgroud)

现在,这应该工作:

int i = 0;
Sum<int> s(i);
std::for_each(vec.begin(), vec.end(), s);
std::cout << "Sum of all numbers: " << s1.result() << std::endl;
Run Code Online (Sandbox Code Playgroud)

但是你必须要注意确保i足够的寿命不会成为Sum<T>::val悬挂参考.