为什么std :: make_move_iterator可以在vector< string>但不在vector< int>上 [英] Why std::make_move_iterator works on vector<string> but not on vector<int>

查看:163
本文介绍了为什么std :: make_move_iterator可以在vector< string>但不在vector< int>上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我原以为std::make_move_iterator总是会移动内容,但事实并非如此.

I was expecting that std::make_move_iterator will always move contents, but it seems not.

似乎正在移动vector<string>中的元素,但不在vector<int>中.

It looks like it is moving elements in vector<string> but not in vector<int>.

请参见以下代码段:

#include <iostream>
#include <iterator>
#include <string>
#include <vector>

void moveIntVector()
{
  std::cout << __func__ << std::endl;
  std::vector<int> v1;
  for (unsigned i = 0; i < 10; ++i) {
    v1.push_back(i);
  }
  std::vector<int> v2(
    std::make_move_iterator(v1.begin() + 5),
    std::make_move_iterator(v1.end()));
  std::cout << "v1 is: ";
  for (auto i : v1) {
    std::cout << i << " ";
  }
  std::cout << std::endl;

  std::cout << "v2 is: ";
  for (auto i : v2) {
    std::cout << i << " ";
  }
  std::cout << std::endl;
}

void moveStringVector()
{
  std::cout << __func__ << std::endl;
  std::vector<std::string> v1;
  for (unsigned i = 0; i < 10; ++i) {
    v1.push_back(std::to_string(i));
  }
  std::vector<std::string> v2(
    std::make_move_iterator(v1.begin() + 5),
    std::make_move_iterator(v1.end()));
  std::cout << "v1 is: ";
  for (auto i : v1) {
    std::cout << i << " ";
  }
  std::cout << std::endl;

  std::cout << "v2 is: ";
  for (auto i : v2) {
    std::cout << i << " ";
  }
  std::cout << std::endl;
}

int main()
{
  moveIntVector();
  moveStringVector();
  return 0;
}

结果是:

moveIntVector
v1 is: 0 1 2 3 4 5 6 7 8 9  # I expect this should be `0 1 2 3 4` as well!
v2 is: 5 6 7 8 9 
moveStringVector
v1 is: 0 1 2 3 4      
v2 is: 5 6 7 8 9 

我在Ubuntu 14.04, gcc 4.8.2上,并且代码是用-std=c++11

I'm on Ubuntu 14.04, gcc 4.8.2 and the code is compiled with -std=c++11

您能解释一下为什么std::make_move_iteratorvector<int>vector<string>上有不同的行为吗? (或者是一个错误?)

Could you explain why std::make_move_iterator have different behaviour on vector<int> and vector<string>? (Or is it a bug?)

推荐答案

该行为是预期的.从这两个向量移动都使原始的v1在其后半部分具有5个可移动的元素.

The behaviour is expected. A move from both vectors leaves the original v1 with 5 moved-from elements in their second half.

区别在于,当移动字符串时,剩下的是空字符串.这是因为这是移动字符串并使离开的字符串保持自洽状态的非常有效的方法(从技术上讲,可以保留它们来保存值"Hello, World, nice move!",但这会产生额外的开销).最重要的是,您不会在输出中看到那些从字符串移出的字符串.

The difference is that when the strings are moved, what is left behind is empty strings. This is because it is a very efficient way to move strings, and leave the moved-from string in a self-consistent state (Technically, they could be left to hold the value "Hello, World, nice move!", but that would incur extra cost). The bottom line is that you don't see those moved-from strings in your output.

对于int向量,无法移动比复制它更有效的int,因此只能将它们复制过来.

In the case of the int vectors, there is no way to move an int that is more efficient than copying it, so they are just copied over.

如果检查向量的大小,则在两种情况下v1的大小都将为10.

If you check the sizes of the vectors, you will see the v1 have size 10 in both cases.

这是一个简化的示例,用于说明从字符串移出的内容为空:

Here's a simplified example to illustrate that the moved from strings are left empty:

#include <iostream>
#include <iterator>
#include <string>
#include <vector>

int main() 
{
    std::vector<std::string> v1{"a", "b", "c", "d", "e"};
    std::vector<std::string> v2(std::make_move_iterator(v1.begin()),
                                std::make_move_iterator(v1.end()));

    std::cout << "v1 size " << v1.size() << '\n';
    std::cout << "v1: ";
    for (const auto& s : v1) std::cout << s << " - ";
    std::cout << '\n';

    std::cout << "v2 size " << v2.size() << '\n';
    std::cout << "v2: ";
    for (const auto& s : v2) std::cout << s << " - ";
    std::cout << '\n';
}

输出:

v1 size 5
v1:  -  -  -  -  - 
v2 size 5
v2: a - b - c - d - e - 

这篇关于为什么std :: make_move_iterator可以在vector&lt; string&gt;但不在vector&lt; int&gt;上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆