【问题标题】:How to construct begin and end iterators in the middle of an array?如何在数组中间构造开始和结束迭代器?
【发布时间】:2019-05-12 15:02:55
【问题描述】:

我正在尝试使用需要两个迭代器的 std::reverse 来反转数组的一部分。当我尝试如下构造迭代器时:

int a[] = {0, 1, 2, 3, 4, 5, 6};
reverse(begin(a + 2), end(a + 4));

我收到一个错误:

template argument deduction/substitution failed:
test.cpp:8:33: note:   mismatched types ‘const std::valarray<_Tp>’ and ‘int*’ reverse(begin(a + 2), end(a + 4));

构造迭代器的正确方法是什么?

【问题讨论】:

  • 我想我找到了一种反转元素的方法,我只需要做 reverse(a+2, a+4);
  • 但我仍然很好奇如何让错误消失。
  • 您自己说过如何让它消失 - 摆脱错误且不应该存在的 beginend 调用。

标签: c++ iterator std reverse


【解决方案1】:

std::beginstd::end 是接受容器并为您提供分别指向第一个和过去一个元素的迭代器的函数。

std::beginstd::end 本身不是迭代器,并且它们不适用于原始指针,因为指针没有任何大小信息。当您调用std::begin(a+2) 时,a 衰减为指向其第一个元素的指针并移动了 2 个元素。结果指针传递给std::begin,但std::begin对指针不起作用,所以结果是编译失败。

要解决您的问题,只需摆脱对std::beginstd::end 的调用:

std::reverse(a+2, a+4);

这是可行的,因为指针满足了迭代器的所有要求,因此a+2a+4 产生的指针完全有效地传递给std::reverse

【讨论】:

  • 什么是容器?它像 Java 中的接口吗?是不是意味着所有的容器都有一个叫做 size 的字段?
  • 我希望我能接受你的两个答案,哈哈。他们都回答了我的问题:D
  • @Aditya 或多或少是的。它们没有像 Java 那样使用 OOO 接口实现,但它们具有通用名称,因此您可以在模板中以这种方式对待它们。
  • Container 是一个概念。类似于java接口,但没有继承关系。
【解决方案2】:

迈尔斯是对的​​。

但是,如果您出于其他原因需要迭代器(例如,它并不总是一个数组),您可以这样做。

你只需要增加迭代器,而不是你构造它的数组:

reverse(begin(a) + 2, begin(a) + 4);

(当我认为您的意思是begin时,您还写了end!)

【讨论】:

  • 我认为他的意思是“结束”,如“我希望结束迭代器指向 a+4”。在这种情况下,代码应该是begin,但end(a) - 3 也可以。
  • @Pete 嗯,我明白了,他们可能认为“开始”和“结束”是某些语言的参数装饰器,而不是 func 调用
  • @LightnessRacesinOrbit:这个问题给人一种非常强烈的印象,即 OP 认为这些是构造函数调用,产生一个 class begin 实例和另一个 class end 实例
  • @Ben 不管 OP 的内部运作如何,它们都不是。
  • @Aditya std::begin(a) 为您提供a 开头的迭代器,然后您可以将其视为任何其他迭代器*,包括向其中添加内容(* 并非每个迭代器都支持随机访问,例如那个,但现在已经足够接近了)
猜你喜欢
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2010-12-09
相关资源
最近更新 更多