无法取消引用向量迭代器的范围-问题是什么?

时间:2019-09-13 17:55:33

标签: c++ vector iterator

我试图使用向量实现阶乘。假定结果附加了vector<int> Res

 //corrected
 vector<int> Res;
 vector<int> Fact;

   for(int i=1; i!=4; i++)
        Fact.push_back(i);

int result=1;
  for (auto i = Fact.rbegin(), auto e= Fact.rend(); i != e; ++i)
      result *= *i; 

Res.push_back(result);

问题出在迭代器中。例外:无法取消引用超出范围的向量迭代器。 我不明白什么是迭代器超出范围? BegEnd是在填充Fact之后定义的。所以有什么问题?我只是个初学者,我一定错过了此主题中一些重要的细节)

3 个答案:

答案 0 :(得分:3)

End是最后一个元素之后的迭代器,您不应取消引用它(End-i为0时Endi):

for (int i = 0; End != Beg; End--, i++)
      result *= *(End-i); 

我想你需要这个:

for (; End != Beg; End--)
      result *= *(End-1); 

答案 1 :(得分:2)

保留语义的最简单方法是使用reverse_iterator

for (auto i = Fact.rbegin(), e = Fact.rend(); i != e; ++i)
   result *= *i;

或者,使用accumulate

result = std::accumulate(Fact.rbegin(), Fact.rend(), 0, [](int a, int b) { return a * b; })

或者,对于C ++ 20和ranges

for (int i : std::ranges::reverse_view{Fact}) 
    result *= i;

或者,由于乘法是可交换的,因此上述任何方法都具有正向迭代。

或者,由于乘以0会产生任意数字0,并且您从0开始:

result = 0;

答案 2 :(得分:0)

  1. end()返回“最后一个元素之后的一个”。第一次通过 i == 0,因此“末尾减去零等于kaboom”。

  2. 如果您碰巧知道正在处理向量/连续存储器,则只要知道结果是有效索引(n <= 0或n > =大小都不好)。对于此代码,我根本不会使用迭代器。