views:

342

answers:

2

Let's say I have a function:

typedef std::vector<int> VecType;
VecType randomVector();

int processing()
{
    VecType v = randomVector();
    return std::accumulate(v.begin(), v.end(), 0);
}

Does C++0x specifically say the spurious copy will be averted from the return value of randomVector? Or would a compiler need to implement the RVO? It seems to me like the value randomVector() should be treated as an rvalue, and thus v's move constructor should be called, but I'm not completely sure this is true.

+7  A: 

The rule is the following

  • If the compiler can do RVO, then it is allowed to do it, and no copy and no move is made.
  • Otherwise, the appropriate constructor is taken.

Like you say, the temporary is an rvalue, and thus the move constructor is selected, because of a rule in 13.3.3.2/3, which says that a rvalue reference binds to an rvalue better than an lvalue reference. In deciding whether to use the move or the copy constructor, overload resolution will therefor prefer the move constructor.

The rule that the compiler is allowed to perform RVO is written at 12.8/15.

Johannes Schaub - litb
+2  A: 

All return values are considered to be rvalues so if the compiler doesn't implement RVO on this case it must use the move constructor rather than the copy constructor.

Motti
I'm not sure how to interpret the "must use the move". AFAIU, assumed a compiler with U/NRVO support, the decision flow is as follows:1) if RVO-friendly, optimize any move/copy operation,2) else if move construtor available, use it3) else if copy constructor available, use it4) else ill-formed program
mloskot
@mloskot I mean the move constructor is selected since it's a better fit for overloading than the copy constructor.
Motti
@Motti Got it. The implicit assumption that move ctor exists was unclear to me. As move ctor is selected, but only if it exists.
mloskot