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.