简体   繁体   中英

C++11 Convenience wrapper for std::reverse()

Is this the right way to use C++11 rvalue-references and move semantics to implement a convenience wrapper for std::reverse() ?

template <class BIDirContainer> inline BIDirContainer&& reverse(BIDirContainer a) {
    std::reverse(begin(a), end(a));
    return std::move(a); 
}

The code works in my test case but I am unsure its about performance: should I use && here or is it unneccesary?

If you return by (rvalue) reference then you will get a dangling reference, since a is a local object. Return by value, and everything should "just work".

I would say the right way to do it is to return by value from your function:

template <class BIDirContainer> inline BIDirContainer reverse(BIDirContainer a) {
    std::reverse(begin(a), end(a));
    return a; 
}

and then give BIDirContainer a move constructor if it doesn't have one. Then this kind of expression:

BIDirContainer x = ...;
BIDirContainer backwards{reverse(x)};

should move the contents of the temporary a in your reverse function into backwards .

So if you want to modify the parameter...

template <class BIDirContainer>
inline BIDirContainer& reverse(BIDirContainer& a)
{
    std::reverse(begin(a), end(a));
    return a;
}

If you want to make a reversed copy then:

template <class BIDirContainer>
inline BIDirContainer reverse(BIDirContainer a)
{
    std::reverse(begin(a), end(a));
    return a;
}

The return value of a function is already an rvalue (specifically an "xvalue"). If you pass it to a function that has move semantics, it will be moved - however due to the named return value optimization (NRVO) result in the above may even be constructed in-place (better than move semantics).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM