0

I have questions regarding make_move_iterator. First when make_move_iterator is used in f2(), similar to Stroustrup C++ 4th Ed Page 964, it will not compile. Does anyone know if this is it's correct use and why it wont compile?

Also, in the other examples, I expected data to be moved out of the source vector, however the results show that it remains. Is this expected?

#include <iterator>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

void f0()
{
    // Use constructor method
    vector<int> v {0, 1, 2, 3};
    vector<int> v2 {make_move_iterator(v.begin()),
                    make_move_iterator(v.end())};
    cout << endl << "f0: v orig (should be moved from)" << endl;
    copy(v.begin(), v.end(), ostream_iterator<int>(cout, ","));
    cout << endl << "f0: v2 copy output" << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, ","));
    cout << endl;
}

void f1()
{
    vector<int> v {0, 1, 2, 3};
    vector<int> v2;

    // Use copy method
    copy(make_move_iterator(v.begin()), make_move_iterator(v.end()),
         back_inserter(v2));
    cout << "f1: orig output (should be moved from)" << endl;
    copy(v.begin(), v.end(), ostream_iterator<int>(cout, ","));
    cout << endl << "f1: copy output" << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, ","));
    cout << endl << "f1: end copy output" << endl;
}

void f2()
{    
   vector<int> v {0, 1, 2, 3};
   vector<int> v2;
// will not compile, example in Stroustrup C++ 4th Ed Page 964
//   copy(v.begin(), v.end(), make_move_iterator(back_inserter(v2)));
}


void f3()
{
    vector<int> v {0, 1, 2, 3};
    vector<int> v2(v.size());

    // Use copy method
    copy(make_move_iterator(v.begin()), make_move_iterator(v.end()),
         v2.begin());
    cout << "f1: orig output (should be moved from)" << endl;
    copy(v.begin(), v.end(), ostream_iterator<int>(cout, ","));
    cout << endl << "f1: copy output" << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<int>(cout, ","));
    cout << endl << "f1: end copy output" << endl;
}

int main()
{
    f0(); f1(); f2(); f3();
    return 0;
}

Compilation and results:

clang++ -std=c++11 -pedantic -Wall test235.cc && ./a.out

f0: v orig (should be moved from)
0,1,2,3,
f0: v2 copy output
0,1,2,3,
f1: orig output (should be moved from)
0,1,2,3,
f1: copy output
0,1,2,3,
f1: end copy output
f3: orig output (should be moved from)
0,1,2,3,
f3: copy output
0,1,2,3,
f3: end copy output

Compilation finished at Sun Aug  2 21:47:27
notaorb
  • 1,944
  • 1
  • 8
  • 18
  • Restrict yourself to one question at a time; your second question is an exact dup of [C++ move iterator and int vector](https://stackoverflow.com/q/63200491/364696) and effectively answered by [copy vs std::move for ints](https://stackoverflow.com/q/27888873/364696), so stick to the first question only. – ShadowRanger Aug 03 '20 at 02:00
  • Why do you think that it won't compile? – eerorika Aug 03 '20 at 02:03
  • `make_move_iterator` requires that its argument's type satisfy *LegacyInputIterator*. Whereas `back_inserter` produces an output iterator. It doesn't make any sense to try and make the destination movable - it's the source of the move that needs to be movable. – Igor Tandetnik Aug 03 '20 at 02:03
  • *" I expected data to be moved out of the source vector"* How exactly did you expect this fact to manifest itself? How do you plan to demonstrate that it did or didn't happen? In any case, for plain `int`s move behaves the same as copy. – Igor Tandetnik Aug 03 '20 at 02:07

1 Answers1

0

To see make_move_iterator() moving elements, you cannot use a vector of ints. It's the source iterators that must be passed to make_move_iterator, not the destination. Instead I use the following code which shows the move iterator working.

#include <iterator>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

struct X {
    int i;
    X(int ii) : i{ii} {}
    X(const X& x) : i{x.i} {} 
    X(X&& x) : i{x.i} {x.i = 0;}
    X& operator=(const X& x)
        {X tmp{x}; swap(*this, tmp); return *this;}
    X& operator=(X&& x) {swap(i, x.i); return *this;}
};
ostream& operator<<(ostream& os, const X& b)
{
    return os << b.i;
}

void f0()
{
    // Use constructor method
    vector<X> v {X(0), X(1), X(2)};
    vector<X> v2 {make_move_iterator(v.begin()),
                  make_move_iterator(v.end())};
    cout << endl << "f0: v orig (should be moved from)" << endl;
    copy(v.begin(), v.end(), ostream_iterator<X>(cout, ","));
    cout << endl << "f0: v2 copy output" << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<X>(cout, ","));
    cout << endl;
}

void f1()
{
    vector<X> v {X(0), X(1), X(2)};
    vector<X> v2;
    copy(make_move_iterator(v.begin()),
         make_move_iterator(v.end()), back_inserter(v2));
    cout << endl << "f1: v orig (should be moved from)" << endl;
    copy(v.begin(), v.end(), ostream_iterator<X>(cout, ","));
    cout << endl << "f1: v2 copy output" << endl;
    copy(v2.begin(), v2.end(), ostream_iterator<X>(cout, ","));
    cout << endl;
}

int main()
{
    f0(); f1();
    return 0;
}

With compilation and output:

clang++ -std=c++11 -pedantic -Wall test235.cc && ./a.out

f0: v orig (should be moved from)
0,0,0,
f0: v2 copy output
0,1,2,

f1: v orig (should be moved from)
0,0,0,
f1: v2 copy output
0,1,2,
notaorb
  • 1,944
  • 1
  • 8
  • 18