【问题标题】:Passing pointer instead of iterator to std::copy将指针而不是迭代器传递给 std::copy
【发布时间】:2017-05-13 12:37:30
【问题描述】:

在进行代码审查时发现此代码:

std::array<uint, 10> expArray2 = {92,130,169,951,634,187,377,233,865,944};
copy(&expArray2[0], &expArray2[10], back_inserter(expected));
                        ^~~~Is this Undefined behavior as ArrayIndexOutOfBoundAccess?

和(我建议的)一样吗:

std::copy ( expArray2, expArray2+10, expected.begin() ); 

我的同事说 1.) 两者都相同 2.) 没有未定义的行为?

我向他解释,指针和迭代器是different 的两个东西,还有std::copy 签名:

template <class InputIterator, class OutputIterator>
  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result); 

有人可以向我确认/解释一下吗如果我在任何地方都错了

【问题讨论】:

  • 指针是一种迭代器。您提供的链接中甚至提到了这一点。
  • 是的,但我主要关心的是 arrayIndexOutOfBoundAccess。
  • 似乎这个问题的核心是关于表达式&amp;expArray2[10]。在这种情况下,这看起来很相关:stackoverflow.com/questions/988158/…
  • 是的,你没看错。

标签: c++ pointers iterator copy indexoutofboundsexception


【解决方案1】:

std::copystd::array 的用法是完全有效的。基本上 std::copy 与表示输入范围的指针一起工作,因为指针满足输入迭代器的所有要求。

至于将输入范围的begin endend作为&expArray2[0]&expArray2[10] 这也很好,因为 std::array 保证管理一个连续的底层数组,因此您可以像处理任何通常的 C 样式数组一样处理这个数组。

就我而言,我更喜欢在 std::copy 中使用 std::beginstd::end: p>

std::copy(std::cbegin(expArray2), std::cend(expArray2),
    std::back_inserter(expected));

【讨论】:

    【解决方案2】:

    你的同事是对的。

    Iterator 是一个有要求的概念(它们可以被取消引用和递增是最低限度的),它指向 fullfil。

    此外,C++ 中的范围是半开的,这意味着传递给算法的第二个(最后一个)迭代器需要过去您希望包含在范围中的元素。它永远不会被取消引用(由 C++ 标准保证),因此您发布的代码没有 UB。

    注意:expected.begin()back_inserter(expected) 不同。对于前者,您需要一个足够大的容器来容纳结果范围,而后者会自动扩展它。

    【讨论】:

    • 您可能想评论back_inserter(expected)expected.begin() 的使用。
    • @user2899162 做到了。你是对的,这有点可疑。
    • 我知道这个区别,向量之前没有提供大小。所以没关系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 2018-07-07
    • 1970-01-01
    相关资源
    最近更新 更多