If I understand it correct, a=std::move(b)
binds reference a to the address of b. And after this operation the content that b points to is not guaranteed.
The implementation of move_iterator
here has this line
auto operator[](difference_type n) const -> decltype(std::move(current[n])) { return std::move(current[n]); }
However, I don't think it makes sense to std::move
an element in an array. What happens if a=std::move(b[n])
?
The following example confuses me also:
std::string concat = std::accumulate( std::move_iterator<iter_t>(source.begin()), std::move_iterator<iter_t>(source.end()), std::string("1234"));
Since the concat
will itself allocate a continuous chunk of memory to store the result, which will not have any overlap with source
. The data in source
will be copied to concat
but not moved.
std::move_iteratorIf this iterator is used as an input iterator, the effect is that the values are moved from, rather than copied from.
std::advance in C++ std::advance advances the iterator 'it' by n element positions. Syntax : template void advance (InputIterator& it, Distance n); it : Iterator to be advanced n : Number of element positions to advance. This shall only be negative for random-access and bidirectional iterators.
If I understand it correct,
a=std::move(b)
binds referencea
to the address ofb
. And after this operation the content that b points to is not guaranteed.
Ah, no: a
is not necessarily a reference. The above use of std::move
also grants the compiler permission to call decltype(a)::operator=(decltype(b)&&)
if it exists: such assignment operators are used when during the assignment to a
the value of b
need not be preserved, but b
must still be left in some sane state for destruction.
However, I don't think it makes sense to
std::move
an element in an array. What happens ifa=std::move(b[n])
?
It can make sense... it just means that each array elements may be efficiently assigned/moved to another variable, but only once per element. After they've been moved-from, a properly-written move constructor or assignment operator should leave objects in a valid but unspecified state, which means you'd usually want to set them again before reading from them.
My answer here shows how someone could append/move elements from a list
to a vector
. With current C++ Standards, you can create move_iterators directly like that.
The code below shows how - even with older compilers / C++ Standards - make_move_iterator
can be used with std::copy
if you want to move from the elements in the source iterator range.
#include <iostream> #include <vector> #include <algorithm> #include <iterator> struct X { X(int n) : n_(n) { } X(const X& rhs) : n_(rhs.n_) { } X(X&& rhs) : n_{ rhs.n_ } { rhs.n_ *= -1; std::cout << "=(X&&) "; } X& operator=(X&& rhs) { n_ = rhs.n_; rhs.n_ *= -1; std::cout << "=(X&&) "; return *this; } int n_; }; int main() { std::vector<X> v{2, 1, 8, 3, 4, 5, 6}; std::vector<X> v2{}; std::copy(v.begin() + 2, v.end(), std::insert_iterator(v2, v2.end())); for (auto& x : v) std::cout << x.n_ << ' '; std::cout << '\n'; std::copy(std::make_move_iterator(v.begin() + 2), std::make_move_iterator(v.end()), std::insert_iterator(v2, v2.end())); for (auto& x : v) std::cout << x.n_ << ' '; std::cout << '\n'; }
Output:
2 1 8 3 4 5 6 =(X&&) =(X&&) =(X&&) =(X&&) =(X&&) 2 1 -8 -3 -4 -5 -6
Code can be run / edited on coliru.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With