1

Say I have a simple struct that contains a vector and defines a copy assignment operator, and a function that returns this struct, like so:

struct SimpleStruct
{
    vector< int > vec1;

    operator=( SimpleStruct& other )
    {
         vec1 = other.vec1;
    }
}

SimpleStruct GetStruct();

As I understand it, because I've declared a copy assignment operator, the compiler won't automatically generate a move constructor for SimpleStruct.

So if I use the GetStruct function like this:

SimpleStruct value = GetStruct();

Is the compiler smart enough to move rather than copy the vector when I say vec1 = other.vec1;? Or will I need to explicitly define a move constructor/assignment operator for SimpleStruct to take advantage of a vector move?

obmarg
  • 9,369
  • 36
  • 59
  • 1
    It cannot move anything from `other` when that is `const`. – Bo Persson Feb 23 '12 at 16:51
  • @BoPersson Ah, didn't think of that. Removed the const for the sake of the question. – obmarg Feb 23 '12 at 16:53
  • Just to clarify, the compiler won't automatically generate a move constructor or assignment operator in any scenario. They always have to be provided by the developer, if move semantics are desired. – Collin Dauphinee Feb 23 '12 at 16:58
  • @dauphic Are you sure about that? This question seems to disagree: http://stackoverflow.com/questions/8283589/are-move-constructors-produced-automatically – obmarg Feb 23 '12 at 17:05
  • I may be wrong, and I'm not going to argue with litb, but I just tested and a POD wasn't provided with one. – Collin Dauphinee Feb 23 '12 at 17:09
  • PODs do get move constructors, although there is no direct way to tell, since the move constructor for a POD does the same thing as the copy constructor for a POD. Note: one way to indirectly tell is by using type_traits. – Nevin Feb 23 '12 at 22:21

2 Answers2

3

C++11 has very strict rules about when movement is allowed to happen. And unless a temporary is involved, those rules require the explicit use of std::move or a similar cast (such as std::forward in some cases).

Yes, you could move something. But it wouldn't happen by accident; it would have to be deliberate.

Also, it is generally rude to write a copy-assignment operator that can modify what is being copied. That's why they usually take a const&, which pretty much guarantees the inability to move.

Or will I need to explicitly define a move constructor/assignment operator for SimpleStruct to take advantage of a vector move?

In general, this is why you don't explicitly define copy and move constructors. Let the compiler do it's job and generate those for you (unless you're using VC++ which doesn't do its job for move constructors/assignment). Only explicitly write copy/move constructors for lower-level containers; anything larger should just rely on those value types to do their jobs.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
1

Inside a copy constructor or copy assignment operator, copy means copy. The language never makes any contextual adjustment to the contents of a function based on how it is called.

However, it's likely that no copy will occur in SimpleStruct value = GetStruct(); because copy elision applies.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421