简体   繁体   English

std :: move两个双端队列-输入与输出迭代器

[英]std::move on two deques - input vs output iterators

take a look at the following code: 看一下下面的代码:

#include <algorithm>
#include <deque>
#include <iostream>

using namespace std;

int main()
{
  deque<int> in {1,2,3};
  deque<int> out;
  // line in question
  move(in.begin(), in.end(), out.begin());
  for(auto i : out)
    cout << i << endl;

  return 0;
}

This will not move anything. 这不会移动任何东西。 Looking at the example here , one must write the line in question like this: 这里的示例,必须这样编写相关的行:

move(in.begin(), in.end(), std::back_inserter(out));

This makes sense in a way, as std::move expects its first two arguments to be InputInterator s (which is satisfied here) and the third one to be an OutputIterator (which out.begin() is not). 这在某种意义上是有道理的,因为std :: move期望它的前两个参数是InputInterator s(在这里满足),第三个参数是OutputIteratorout.begin()不是)。

What does actually happen if the original code is executed and move is passed an iterator that is not an OutputIterator? 如果执行原始代码并将move传递给不是OutputIterator的迭代器,那么实际上会发生什么? Why does C++'s type-safety not work here? 为什么C ++的类型安全在这里不起作用? And why is the construction of an output-iterator delegated to an external function, ie why does out.backInserter() not exist? 以及为什么将输出迭代器的构造委托给外部函数,即为什么out.backInserter()不存在?

The original code tries to dereference and increment out.begin() . 原始代码尝试取消引用并增加out.begin() Since out is empty, that's a past-the-end iterator, and it can't be dereferenced or incremented. 由于out为空,因此它是一个过去的迭代器,因此无法取消引用或递增。 Doing so gives undefined behaviour. 这样做会产生不确定的行为。

std::move expects [...] the third one to be an OutputIterator (which out.begin() is not). std::move期望第三个是OutputIteratorout.begin()不是)。

Yes it is. 是的。 Specifically, it's a mutable random access iterator, which supports all the operations required of an output iterator, and more. 具体来说,它是一个可变的随机访问迭代器,它支持输出迭代器所需的所有操作,以及更多其他功能。

What does actually happen if the original code is executed and move is passed an iterator that is not an OutputIterator ? 如果执行了原始代码并将move传递给了一个不是OutputIterator的迭代器,那么实际上会发生什么?

That would cause a compile error if the iterator didn't support the operations required of an output iterator needed by the function; 如果迭代器不支持函数所需的输出迭代器所需的操作,则将导致编译错误; or undefined behaviour if the operations existed but did something other than that required of an output iterator. 或未定义的行为(如果操作存在但执行了输出迭代器要求的操作以外的操作)。

Why does C++'s type-safety not work here? 为什么C ++的类型安全在这里不起作用?

Because the type is correct. 因为类型正确。 The incorrect runtime state (being a past-the-end iterator, not the start of a sequence with at least as many elements as the input range) can't be detected through the static type system. 无法通过静态类型系统检测到错误的运行时状态(是过去的迭代器,而不是至少具有与输入范围一样多的元素的序列的开始)。

why does out.backInserter() not exist? 为什么out.backInserter()不存在?

That would have to be written separately for all sequence containers: both the standard ones, and any others you might define yourself. 必须为所有序列容器分别编写:标准容器和您可能定义的任何其他容器。 The generic function only has to be implemented once, in the standard library, to be usable for any container that supports push_back . 泛型函数只需在标准库中实现一次,即可用于支持push_back任何容器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM