Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I know if I'm using copy or move?

Do I understand it right that the C++14 standard library uses move semantics? In other words, can I be confident that I am using a move instead of a copy in the following program:

#include <iostream>
#include <string>
#include <vector>

using namespace std::string_literals;

std::vector<std::string> greeting()
{
    std::vector<std::string> vs {"hello"s, "world"s};
    return vs;
}

int main()
{
    std::vector<std::string> s = greeting();
    std::cout << s[0] << " " << s[1] << "\n" ;
}

Is there a way I can check?

How about in the following example:

#include <iostream>
#include <string>
#include <vector>

using namespace std::string_literals;

class Greeting {
    public:
    std::string first, second;
    Greeting() { first = "hello"s ; second = "world"s ;};
};

Greeting greetingc()
{
    Greeting g;
    return g;
}

int main()
{
    Greeting g = greetingc();
    std::cout << g.first << " " << g.second << "\n" ;
}

Move, or copy?

like image 441
blippy Avatar asked Jun 07 '16 09:06

blippy


People also ask

When should you use std :: move?

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object.

Does STD copy move?

std::move is actually just a request to move and if the type of the object has not a move constructor/assign-operator defined or generated the move operation will fall back to a copy.

What is std :: move doing?

std::move() is a cast that produces an rvalue-reference to an object, to enable moving from it.

What is Move semantics in C++?

Move semantics allows you to avoid unnecessary copies when working with temporary objects that are about to evaporate, and whose resources can safely be taken from that temporary object and used by another.


1 Answers

In most cases there is not much difference between copy and move. It is only interesting when you have ownership ower something which you do not want to duplicate. Like a socket or memory allocated to the object. So only interesting when something is both expensive (like copy a huge chunk of memory when you need only one of that) and you have to take care of ownership (not having two pointers pointing to the same memory, or a socket, etc...).

In both of your examples what is most likely to happen is that the compiler will do RVO return-value optimization, which removes the need of a copy or move. Vector defines move so the compiler will use move semantics whenever it can (rvalue semantics), and you can force it with std::move. But neigher of your examples will be any faster because of it. Read more about move.

If you are curious you can implement both copy and move and place write to the console from them.

Greeting(const Greeting& g)
{
    std::cout << "Copy";
    // Copy it
}

Greeting(Greeting&& g)
{
    std::cout << "Move";
    // Move it
}

Usually this is what happens.

Greeting foo(){ Greeing a; return a; }
Greeting a; // Normal construction
Greeting b(a); // Copy of 'a'
Greeting c(std::move(a)); // Move, 'a' will be changed
Greeting d(foo()); // Move from rvalue which is returned from foo() unless RVO kicks in
like image 125
Matzi Avatar answered Sep 22 '22 10:09

Matzi