Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
277 views
in Technique[技术] by (71.8m points)

c++ - Are std::move and std::copy identical?

I tried to do something like:

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

And got this error:

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

Which seemed confusing to me. The same thing happens if you use std::move. It appears that GCC internally uses a function called std::__copy_move_a which moves rather than copies. Does it matter whether you use std::copy or std::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.
";
    }

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

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

    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;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

std::move(a, b, c); is semantically identical to

std::copy(std::make_move_iterator(a),
          std::make_move_iterator(b),
          c);

Your efforts to use them both failed because the third argument - the output iterator - should not be a move iterator. You are storing into the third iterator, not moving from it. Both

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

and

std::move(s1.begin(), s1.end(), s2.begin());

should do what you want.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...