将指针而不是迭代器传递给std :: copy

时间:2016-12-29 07:56:41

标签: c++ pointers iterator copy indexoutofboundsexception

在进行代码审查时找到此代码:

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); 

有人可以向我确认/解释这个如果我错了吗

2 个答案:

答案 0 :(得分:3)

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

至于&amp; expArray2 [0] &amp; expArray2 [10]输入范围的开始结束结束 ] 它也没问题,因为 std :: array 可以保证管理一个连续的底层数组,所以你可以像处理任何常见的C风格数组一样处理这个数组。

至于我,我更喜欢在 std :: copy 中使用 std :: begin std :: end

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

答案 1 :(得分:1)

你的同事是对的。

Iterator是一个具有要求的概念(它们可以被解除引用并且递增是最小的)指针fullfil。

此外,C ++中的范围是半开放的,这意味着传递给算法的第二个(最后一个)迭代器需要一个要包含在范围内的元素。它永远不会被解除引用(这是由C ++标准保证的),所以你发布的代码没有UB。

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