Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do we practically need 'explicit xvalues'?

Tags:

c++

c++11

The definition of xvalue is as follows:

— An xvalue (an “eXpiring” value) also refers to an object, usually near the end of its lifetime (so that its resources may be moved, for example). An xvalue is the result of certain kinds of expressions involving rvalue references (8.3.2). [ Example: The result of calling a function whose return type is an rvalue reference is an xvalue. —end example ]

Will we ever fall into where we practically need to use a function whose return type is an rvalue reference, which is an xvalue?

const int && Foo()
{
    // ...
}

Move semantics take an rvalue reference as a parameter, not a return value. So I don't think that's the case.

like image 434
Dean Seo Avatar asked Jan 19 '16 07:01

Dean Seo


1 Answers

Returning rvalue references can be of use for functions that already take rvalues as parameters. A simple example:

struct X {
    X() = default;
    X(X&& other) { std::cout << "move ctor\n"; }
    X(X const&) = delete;
    void log(std::string const& s){ std::cout << "log: " << s << "\n"; }
};

void sink(X&& x) { 
    x.log("sink"); 
}

X&& passOn(X&& in) {
    in.log("pass");
    return std::move(in);
}

X moveOn(X&& in) {
    in.log("move");
    return std::move(in);
}

int main() {
    sink(passOn(X()));
    std::cout << "===============================\n";
    sink(moveOn(X()));
}

Live demo →

The second function will call the move constructor to create the returned object, while the first will pass on the reference it already got. This is more useful if we don't return the original reference but instead a reference to a part of the referred object, e.g.

template<class T>
T&& getHead(std::vector<T>&& input) {
    return std::move(input.front());
}
like image 62
Arne Mertz Avatar answered Sep 20 '22 20:09

Arne Mertz