c++ 看起来std::move_iterator只能处理字符串数据类型

mrwjdhj3  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(216)

如果容器具有字符串类型的数据,则可以使用move_iterator将数据从源容器移动到目标容器。Move_iterator不对容器中的其他数据类型进行操作。

move_iterator工作正常

  1. #include <iostream> // std::cout
  2. #include <iterator> // std::move_iterator
  3. #include <vector> // std::vector
  4. #include <string> // std::string
  5. #include <algorithm> // std::copy
  6. using namespace std;
  7. int main () {
  8. vector<string>src = {"one", "two", "three", "four"}, des(4);
  9. using Iter = vector<string>::iterator;
  10. //move the data from src to des
  11. move_iterator<Iter>beginitr(src.begin());
  12. move_iterator<Iter>enditr(src.end());
  13. Iter diter = des.begin();
  14. while(beginitr != enditr)
  15. {
  16. *diter++ = *beginitr++;
  17. }
  18. cout << "src container size: " << src.size() << endl;
  19. cout << "data: " ;
  20. for_each(begin(src),end(src), [](string x){cout << x ;});
  21. cout << endl << "THE END";
  22. return 0;
  23. }

输出

src容器大小:4数据:THE END

move_iterator不移动数据

  1. #include <iostream> // std::cout
  2. #include <iterator> // std::move_iterator
  3. #include <list> // std::vector
  4. #include <string> // std::string
  5. #include <algorithm> // std::copy
  6. using namespace std;
  7. int main () {
  8. list<int>src = {1,2,3,4}, des(4);
  9. using Iter = list<int>::iterator;
  10. //move the data from src to des
  11. move_iterator<Iter>beginitr = make_move_iterator(src.begin());
  12. move_iterator<Iter>enditr = make_move_iterator(src.end());
  13. Iter diter = des.begin();
  14. while(beginitr != enditr)
  15. {
  16. *diter++ = *beginitr++;
  17. }
  18. cout << "src container size: " << src.size() << endl;
  19. for_each(begin(src),end(src), [](int x){cout << x << endl;});
  20. return 0;
  21. }

输出

src容器大小:四一二三四
看来整数数据被复制到目标容器而不是被移动。

eiee3dmh

eiee3dmh1#

使用move迭代器的唯一区别是,对迭代器的解引用会产生右值引用。如果只有复制赋值操作符可用,而没有移动赋值操作符,则这将用作“回退”。
下面的代码演示了这一点:

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <iterator>
  4. #include <list>
  5. #include <utility>
  6. struct Test
  7. {
  8. #if 0
  9. Test(Test&&)
  10. {
  11. std::cout << "Test::Test(Test&&)\n";
  12. }
  13. Test& operator=(Test&&)
  14. {
  15. std::cout << "Test& Test::operator=(Test&&)\n";
  16. return *this;
  17. }
  18. #endif
  19. Test(Test const&)
  20. {
  21. std::cout << "Test::Test(Test const&)\n";
  22. }
  23. Test& operator=(Test const&)
  24. {
  25. std::cout << "Test& Test::operator=(Test const&)\n";
  26. return *this;
  27. }
  28. Test()
  29. {
  30. std::cout << "Test::Test()\n";
  31. }
  32. };
  33. int main() {
  34. std::list<Test> src(4);
  35. std::list<Test> des(4);
  36. std::cout << "-------------------copy with move iterator--------------------\n";
  37. std::copy(std::make_move_iterator(src.begin()), std::make_move_iterator(src.end()), des.begin());
  38. std::cout << "-------------------copy with normal iterator--------------------\n";
  39. std::copy(src.begin(), src.end(), des.begin());
  40. }

输出#if 0保持原样:

  1. ...
  2. -------------------copy with move iterator--------------------
  3. Test& Test::operator=(Test const&)
  4. Test& Test::operator=(Test const&)
  5. Test& Test::operator=(Test const&)
  6. Test& Test::operator=(Test const&)
  7. -------------------copy with normal iterator--------------------
  8. Test& Test::operator=(Test const&)
  9. Test& Test::operator=(Test const&)
  10. Test& Test::operator=(Test const&)
  11. Test& Test::operator=(Test const&)

定义了移动语义的输出(#if 1而不是#if 0):

  1. ...
  2. -------------------copy with move iterator--------------------
  3. Test& Test::operator=(Test&&)
  4. Test& Test::operator=(Test&&)
  5. Test& Test::operator=(Test&&)
  6. Test& Test::operator=(Test&&)
  7. -------------------copy with normal iterator--------------------
  8. Test& Test::operator=(Test const&)
  9. Test& Test::operator=(Test const&)
  10. Test& Test::operator=(Test const&)
  11. Test& Test::operator=(Test const&)

Godbolt演示
对于像int这样的算术类型,只有复制语义,没有移动语义,在代码中不修改源列表。

展开查看全部

相关问题