-1

I am trying to understand the move iterator. This is the sample code from https://en.cppreference.com/w/cpp/iterator/make_move_iterator

#include <iostream>
#include <list>
#include <vector>
#include <string>
#include <iterator>
 
int main()
{
    std::vector<std::string> s{"one", "two", "three"};
 
    std::vector<std::string> v1(s.begin(), s.end()); // copy
 
    std::vector<std::string> v2(std::make_move_iterator(s.begin()),
                                std::make_move_iterator(s.end())); // move
 
    std::cout << "v1 now holds: ";
    for (auto str : v1)
            std::cout << "\"" << str << "\" ";   //return one, two, three
    std::cout << "\nv2 now holds: ";
    for (auto str : v2)
            std::cout << "\"" << str << "\" ";   //return one, two, three
    std::cout << "\noriginal list now holds: ";
    for (auto str : s)
            std::cout << "\"" << str << "\" ";   //return nothing
    std::cout << '\n';
}

So the move iterator moves as expected. But when I made some minor changes:

    std::vector<int> s{1, 2, 3};
 
    std::vector<int> v1(s.begin(), s.end()); // copy
 
    std::vector<int> v2(std::make_move_iterator(s.begin()),
                                std::make_move_iterator(s.end())); // move

s still references {1, 2, 3} despite moving. Is there a reason for this?

  • There isn't much point to moving `int`s so a move is pretty much the same as a copy. I also don't recommend trying to use objects after moving from them. The only guarantees you get from a moved-from object is you can safely destroy it. Absolutely no guarantees are given about what it contains. – user4581301 Aug 01 '20 at 00:09
  • Supplemental reading: [What can I do with a moved-from object?](https://stackoverflow.com/questions/7027523/what-can-i-do-with-a-moved-from-object) – user4581301 Aug 01 '20 at 00:17

1 Answers1

0

Those outputs are expected. In the first case, you are moving an std::string, which is an object that has a move constructor defined. In the second case, you are moving an int, which is just a number and therefore doesn't have a move constructor.

When you move from the std::string, your program will take the underlying pointer to a dynamic character array and place that pointer into the new string.

When you move from the int, your program won't do anything special because there are no member variables or anything to move around. So really there is no difference between copying and moving an int.

Hopefully this makes sense! Leave a comment if you'd like more explanation and I'll try my best to answer :)

  • Slight tweak: in *there is no dynamic memory or anything to move around* the memory doesn't need to be dynamic. – user4581301 Aug 01 '20 at 00:14
  • @user4581301 Good clarification. To explain that quote, I was referencing the fact that `std::string` maintains dynamic memory and pointing out that an `int` differs from `std::string` in that it does not. – Grant Schulte Aug 01 '20 at 00:17
  • 1
    Understood. But another fun fact: There's no guarantee that a `std::string` contains dynamic memory either. [See Short String Optimization](https://stackoverflow.com/questions/10315041/meaning-of-acronym-sso-in-the-context-of-stdstring) – user4581301 Aug 01 '20 at 00:20
  • Ohhh that's awesome! Thanks for the link, it's a pretty clever concept :O – Grant Schulte Aug 01 '20 at 00:27