Search code examples
c++rvalue-referencelvalue

C++, take const lvalue and rvalue reference in a function


I have a few methods that I need to give them ability to take variable by const lvalue (where it would be copied) and rvalue reference (for speed)

struct Object {
    ...
    Object(Object&& o) { ... }
    Object(const Object& o) { ... }
    ...
};

...

struct SomeClass {
    ...
    Object arr[7];

    void copy(int pos,const Object& o) { arr[pos] = o; }
    void copy(int pos,Object&& o) { arr[pos] = o; }
    ...
};

So, two copy methods are COMPLETELY IDENTICAL in SomeClass. The only difference is that in one Object is passed as const, which will be copied, and in another Object is passed to be consumed for a quick copy as rvalue reference.

The code of these two methods is COMPLETELY IDENTICAL.

Now, it is not that tragic in the example above, however, I have methods that are a little larger, 9-15 lines or so. The workaround is, obviously, to copy them like it was done here, but it doesn't feel right.

How can I reuse the code of copy method?


Solution

  • Universal references and std::forward allow you to implement perfect forwarding. Here's the modified copy:

    template <typename T>
    void copy(int pos, T&& o) {arr[pos] = std::forward<T>(o);}
    

    If you are worried about possible implicit conversions from other types to Object, you can also add a static_assert in the body of copy. If you pass an l-value Object to copy, T will be deduced to be Object&. std::forward<Object&> returns a reference. So, the copy assignment overload will be chosen. If you pass an r-value Object to copy, T will be deduced to be Object. std::forward<Object&> returns Object&&. Since std::forward<Object>(o) is an rvalue as well, the move assignment operator will get picked.