代码之家  ›  专栏  ›  技术社区  ›  smerlin

为什么不能为每个修改它的函数参数?

  •  8
  • smerlin  · 技术社区  · 16 年前

    http://www.cplusplus.com/reference/algorithm/for_each/
    一元函数接受一个元素 范围作为参数。这也可以 是指向函数或 类重载的对象 运算符()。它的返回值,如果有的话, 被忽略。

    根据本文,我期望for_每个人实际上修改作为第三个参数给出的对象,但似乎for_每个人都在一个临时对象上操作,甚至不修改给它的对象。

    那么,为什么它是以这种方式实现的呢?它似乎没那么有用。或者我误解了什么,我下面的代码包含错误?

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    template <class T> struct Multiplicator{
        T mresult;
      public:
        const T& result() const{return mresult;}
        Multiplicator(T init_result = 1){
          mresult = init_result;
        }
        void operator()(T element){
          mresult *= element;
          std::cout << element << " "; // debug print
        }
    };
    
    int main()
    {
        std::vector<double> vec;
        vec.push_back(1);
        vec.push_back(2);
        vec.push_back(3);
        Multiplicator<double> multiply;
        std::for_each(vec.begin(),vec.end(),multiply);
        std::cout << "\nResult: " << multiply.result() << std::endl;
        return 0;
    }
    

    预期输出:

    1 2 3 Result: 6
    

    但得到以下输出:

    1 2 3 Result: 1
    
    3 回复  |  直到 15 年前
        1
  •  15
  •   James McNellis    16 年前

    函数对象由值获取。 for_each 返回函数对象,因此如果将其更改为:

    multiply = std::for_each(vec.begin(),vec.end(),multiply);
    

    你得到了预期的输出。

        2
  •  10
  •   GManNickG    16 年前

    而詹姆斯是正确的,使用 std::accumulate 具有 std::multiplies 可能更正确:

    #include <iostream>
    #include <functional>
    #include <numeric>
    #include <vector>
    
    int main(void)
    {
        std::vector<double> vec;
        vec.push_back(1);
        vec.push_back(2);
        vec.push_back(3);
    
        double result = std::accumulate(vec.begin(), vec.end(),
                                        1.0, std::multiplies<double>());
    
        std::cout << "\nResult: " << result << std::endl;
    
    }
    

    与你 for_each 版本,您不需要再次复制函数,而是:

    double result = std::for_each(vec.begin(), vec.end(), multiply).result();
    

    或者C++0X,用于娱乐:

    double result = 1;
    std::for_each(vec.begin(), vec.end(), [&](double pX){ result *= pX; });
    
        3
  •  0
  •   Yogesh Arora    16 年前

    for-each的语义不适合您要做的事情。Accumulate做的正是你想做的,用它来代替。