Can't make a function accept both rvalue and lvalue references

class Vec3{

private:
    float x, y, z;

public:
    Vec3() = default;
    Vec3(const float c) {x = c; y = c; z = c;}

    static  Vec3& normalize(Vec3& v) {/* normalize */ return v;}

};

Vec3 aaa = Vec3( 1.0f);
Vec3 bbb = Vec3::normalize( Vec3( 1.0f));
Vec3 ccc = Vec3::normalize( aaa);

I wanted to write functions that take vectors as parameters, do some work on them and return them as references.

In the above code bbb will not compile because it's a non-const reference to an rvalue. I can't make it const since normalize needs to modify the object. If I make the function accept rvalue references ( Vec3&& v ) then ccc wont compile since aaa is an lvalue. Can I make this work without having to write two versions of normalize ?

(I'm confused about rvalue vs lvalue references, I don't understand for example why a someFunc(const Vec3& v) will accept both rvalues and lvalues while the non-const version won't.)


You can do this with a little overhead. You wont have to write the normalizing code twice but you need to handle the returning differently as you do not want to return a reference to a rvalue.

If you had something like

static  Vec3& normalize(Vec3& v) {/* normalize */ return v;}
static  Vec3 normalize(Vec3&& v) { return normalize(v);}
                                                    ^ v is a lvalue here

Now you can forward the tempoary to the lvalue reference version and then return by value so that you aren't trying to refer to a object that might not exist anymore.


No, you can't. You have to use two versions. You can combine them as @NathanOliver suggested but you still need two versions.

I don't understand for example why a someFunc(const Vec3& v) will accept both rvalues and lvalues while the non-const version won't.

Because the standard prohibits binding rvalues to non-const lvalue ref. It's the same problem as in

const int& x = 1;  // OK
int& y = 2;  // error

It seems that the standard is trying to protect you from the accidental modifications of temporaries. Unfortunately I can't really give you deeper explanation then that. But you can read this:

Why not non-const reference to temporary objects?

How come a non-const reference cannot bind to a temporary object?

Of course at the end && was invented exactly to allow that. So I guess its more like a historical reason?

链接地址: http://www.djcxy.com/p/40298.html

上一篇: 前/后缀增量的左值和右值

下一篇: 无法使函数接受右值和左值引用