Search code examples
c++c++11move-semanticsrvalue-referencecopy-elision

C++11 constructor argument: std::move and value or std::forward and rvalue reference


Which of the below two should be preferred and why?

struct X {
    Y data_;
    explicit X(Y&& data): data_(std::forward<Y>(data)) {}
};

vs

struct X {
    Y data_;
    explicit X(Y data): data_(std::move(data)) {}
};

Solution

  • The two variants differ in functionality. The following statements work for the second one–but not for the first one:

    Y y;
    X x(y);
    

    If you are looking for the same functionality, the two variants should look as follows:

    struct X
    {
        Y data_;
        explicit X(const Y& data) : data_(data) { }
        explicit X(Y&& data) : data_(std::move(data)) { }
    };
    
    struct X
    {
        Y data_;
        explicit X(Y data) : data_(std::move(data)) { }
    };
    

    The first variant saves one move operation, whereas the second variant is less to write. So, the answer is: Use the latter as long as you have no reason to optimize the performance.