Search code examples
c++c++11rvalue-referencenrvo

Which function structure is better?


Look at the following code:

class MyClass{
public:
    MyClass(){}
    MyClass(MyClass &&){}
    MyClass(const MyClass &){}
};
MyClass f1(){
    MyClass &&o=MyClass();
    /*...*/
    return std::move(o);//or return static_cast<MyClass &&>(o);
}
MyClass f2(){
    MyClass o=MyClass();
    /*...*/
    return o;
}


int main(int, char **){
    auto a=f1();
    auto b=f2();
}

Function f2 is the normal form of returning an object. NRVO may apply and the additional copy constructor call could be avoid. f1 is the new form that uses rvalue reference. For systems that do not support NRVO but support rvalue reference, the move constructor is called rather than copy constructor, which would be considered better in most of the cases.

The problem of f1 is that: are there any compilers that support of NRVO in this case? It seems to be the better form in the future after all.


Solution

  • This is how current compilers (MSVC10 / gcc trunk) works :
    Assuming MyClass is moveable

    f1 : move   
    f2 :   
    worst case : move 
    best case : NRVO 
    

    Assuming MyClass is not moveable :

    f1 : copy    
    f2 :    
    worst case : copy    
    best case : NRVO 
    

    So even if compilers get better and start doing NRVO for functions like f1, why bother complicate the code when f2 classical C++03 functions are already optimal ?