Std :: move e std :: copy são idênticos?

Eu tentei fazer algo como:

std::copy(std::make_move_iterator(s1.begin()), std::make_move_iterator(s1.end()), 
          std::make_move_iterator(s2.begin()));

E recebi este erro:

error: using xvalue (rvalue reference) as lvalue
        *__result = std::move(*__first);

O que me pareceu confuso. O mesmo acontece se você usarstd::move. Parece que o GCC usa internamente uma função chamadastd::__copy_move_a que se move ao invés de copiar. Importa se você usastd::copy oustd::move?

#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <cstring>

struct Test
{
    typedef std::string::value_type value_type;
    std::string data;

    Test()
    {
    }

    Test(const char* data)
        : data(data)
    {
    }

    ~Test()
    {
    }

    Test(const Test& other)
        : data(other.data)
    {
        std::cout << "Copy constructor.\n";
    }

    Test& operator=(const Test& other)
    {
        data = other.data;
        std::cout << "Copy assignment operator.\n";
        return *this;
    }

    Test(Test&& other)
        : data(std::move(other.data))
    {
        std::cout << "Move constructor.\n";
    }

    decltype(data.begin()) begin()
    {
        return data.begin();
    }

    decltype(data.end()) end()
    {
        return data.end();
    }

    void push_back( std::string::value_type ch )
    {
        data.push_back(ch);
    }
};

int main()
{
    Test s1("test");
    Test s2("four");
    std::copy(std::make_move_iterator(s1.begin()), std::make_move_iterator(s1.end()), 
              std::make_move_iterator(s2.begin()));
    std::cout << s2.data;
}

questionAnswers(2)

yourAnswerToTheQuestion