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?
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.
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.
std::move() is a cast that produces an rvalue-reference to an object, to enable moving from it.
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.
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
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