迭代器可以变成指针吗?

时间:2017-08-18 06:38:12

标签: c++ c++11 pointers iterator

在“A Tour of C ++”(第一次印刷)的“13.7.3 async()”中,提供以下内容作为示例:

double comp4(vector<double>& v)
{
  if (v.size() < 10000)
    return accum(v.begin(), v.end(), 0.0);

  auto v0 = &v[0];
  auto sz = v.size();

  auto f0 = async(accum, v0, v0 + sz/4, 0.0);
  auto f1 = async(accum, v0 + sz/4, v0 + sz/2, 0.0);
  auto f2 = async(accum, v0 + sz/2, v0 + sz*3/4, 0.0);
  auto f3 = async(accum, v0 + sz*3/4, v0 + sz, 0.0);

  return f0.get() + f1.get() + f2.get() + f3.get();
}

其中accum的定义如下:

double accum(double* beg, double* end, double init)
{
  return accumulate(beg, end, init);
}

vectorasyncaccumulate是标准库版本。

运行此命令会产生以下错误:

error: cannot convert ‘std::vector<double>::iterator {aka __gnu_cxx::__normal_iterator<double*, std::vector<double> >}’ to ‘double*’ for argument ‘1’ to ‘double accum(double*, double*, double)’
     return accum(v.begin(), v.end(), 0.0);

如果我改用return accum(&v[0], &v[0] + v.size(), 0.0);,我可以使用它。我在原始配方中做错了吗?  vector<double>::iterator能否转换为double*或者这本书是错误的吗?本书第一版和第二版的勘误表中似乎没有提到这个问题。

1 个答案:

答案 0 :(得分:3)

指定std::vector的方式,完全有可能通过让vector<T>::iterator成为T*的typedef来实现它。

可能的是,编写该代码的人碰巧有vector的版本以这种方式实现并且很幸运。

假设accum()的定义没有改变,您的解决方法是正确的方法。

在我看来,accum应该这样声明:

template<typename T, typename ITE>
T accum(ITE beg, ITE end, T init);

但那基本上是std::accumulate,所以它只是多余的。