7

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?

Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160
blippy
  • 1,490
  • 1
  • 13
  • 22
  • Where exactly do you want to check? What line of code should be a move? – rubenvb Jun 07 '16 at 10:09
  • @rubenvb I mean that when the return statement is called from either of greeting(0 or greetingc(), what does the program do: does it copy the object (a potentially expensive operation) or does it move the object (a cheap operation). – blippy Jun 07 '16 at 10:23
  • In general, whenever temporary object are created, which you do not have access to, are good candidate for `move semantics`. – sameerkn Jun 07 '16 at 10:38
  • Maybe [related](http://stackoverflow.com/questions/28476393/how-to-know-or-test-if-a-given-type-is-going-to-be-moved). – PaperBirdMaster Jun 07 '16 at 12:50

1 Answers1

2

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
Community
  • 1
  • 1
Matzi
  • 13,770
  • 4
  • 33
  • 50