【问题标题】:boost lambda for_each / transform puzzleboost lambda for_each / 变换拼图
【发布时间】:2008-11-25 11:39:57
【问题描述】:

有人知道原因吗

  vector<int> test(10);
  int a=0;

  for_each(test.begin(),test.end(),(_1+=var(a),++var(a)));

  for_each(test.begin(),test.end(),(cout << _1 << " "));
  cout << "\n"

给出:“0 1 2 3 4 5 6 7 8 9”

但是

  transform(test.begin(),test.end(),test.begin(), (_1+=var(a),++var(a)));
  ...(as before)

给出:“1 2 3 4 5 6 7 8 9 10”

?

【问题讨论】:

    标签: c++ boost lambda


    【解决方案1】:

    逗号运算符从左到右计算,所以结果

    _1+=var(a), ++var(a)
    

    是 ++var(a),您将使用转换版本存储它。

    • for_each:

      _1 += var(a) 被评估,更新您的序列(通过 lambda _1),然后 ++var(a) 被评估,但这对您的序列没有影响。

    • 变换:

      _1+=var(a) 被评估,更新你的序列(就像以前一样),然后 ++var(a) 被评估,这也给出了整个表达式的结果,然后用于再次更新你的序列(通过变换)

    【讨论】:

      【解决方案2】:

      本质上,在for_each 中,您提供了一个具有副作用的函数,而在transform 中,您使用了函数的返回值。

      在您的情况下,您重复使用相同的功能。由于operator += 恰好有一个返回值,所以这是作为转换结果使用的那个。

      【讨论】:

        【解决方案3】:

        变换(test.begin(),test.end(),test.begin(), (_1+=var(a),++var(a)));

        这将转化为

        int doit(int & elem) {
            elem += a;
            return ++a;
        }
        
        for each elem : elem = doit(elem);
        

        以 a=0 开头将在第一次运行时产生 1。我们将 a 递增 10 次,因此我们将在最后一次运行中得到 10。


        for_each(test.begin(),test.end(),(_1+=var(a),++var(a)));

        这将转化为

        void doit(int & elem) {
            elem += a;
            ++a;
        }
        
        for each elem : doit(elem);
        

        从 a=0 开始,第一次运行我们会得到 0。我们将 a 增加 10 次,但在增加之前分配它。因此最后一个数字是 9。

        我希望现在将这两个函数转换为普通函数时很清楚。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-06
          相关资源
          最近更新 更多