3

考虑一下 -

#include <iostream>
#include <algorithm>
#include <functional>
#include <iterator>
#include <list>

int main()
{
  typedef std::list<int> L;
  L l(5);
  typedef L::const_iterator CI;
  typedef L::iterator I;
  CI cb = l.begin(), ce = l.end();
  I b = l.begin();
  std::transform(cb, --ce, ++b, std::bind2nd(std::plus<CI::value_type>(), 1));
  std::copy(l.begin(), l.end(), std::ostream_iterator<CI::value_type>(std::cout\
));
  std::cout<<std::endl;
  return 0;
}

根据我的说法,它的输出应该是 01111,因为变换将从列表的第一个到“倒数第二个”元素进行迭代,将每个元素加 1 并从“第二个”元素覆盖到“最后一个”元素。

但令我惊讶的输出是 01234

我错过了什么?我阅读了 cppreference 上的转换文档

4

2 回答 2

3

这是因为您将每个单独转换的结果存储到容器的下一个元素中,因此转换函数的下一个输入将是前一个转换的输出(因为您如何定义输入和输出范围)。

换句话说,transform()算法将处理容器的第一个元素 ( 0),添加1到它,并将结果 ( ) 存储为同一容器1的第二个元素。然后,它将处理第二个元素,即 now ; 它将添加到其中,并将结果 ( ) 存储为容器的第三个元素。依此类推,直到你到达最后一次迭代。112

如果要获取输出01111,则应将转换结果存储到不同的容器中(现场示例):

std::vector<int> out(l.size());
std::transform(cb, --ce, ++out.begin(), 
//                       ^^^^^^^^^^^^^
    std::bind2nd(std::plus<CI::value_type>(), 1));

或者使用不同的迭代策略,如 DyP 在评论中建议的那样现场示例):

 std::transform(++cb, ce, ++b, std::bind2nd(std::plus<CI::value_type>(), 1));
于 2013-06-26T13:43:56.873 回答
3

由于您开始在 处将元素添加到同一个容器中++b,因此存在一个偏移量,这意味着您将元素i加号1插入到 位置i+1。因此,随着您的前进,您正在累积总和。假设 transform 按顺序处理元素,这就是前三个迭代将执行的操作:

0 0 0 0 0

将 1 添加到位置 0,将其放在位置 1

0 1 0 0 0

将 1 加到位置 1,将其放在位置 2

0 1 2 0 0

将 1 加到位置 2,将其放在位置 3

0 1 2 3 0

于 2013-06-26T13:46:16.750 回答