无法使函数接受右值和左值引用
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);
我想编写以矢量为参数的函数,对它们做一些处理并将它们作为参考返回。
在上面的代码中, bbb
不会编译,因为它是对右值的非常量引用。 由于normalize
需要修改对象,因此我无法将其设置为const。 如果我让函数接受右值引用( Vec3&& v
),那么ccc
不会编译,因为aaa
是一个左值。 我可以做这个工作,而不必写两个normalize
版本吗?
(我对rvalue和lvalue的引用感到困惑,我不明白为什么someFunc(const Vec3& v)
会接受rvalue和lvalues,而非const的版本不会。)
你可以做一点点的开销。 你不必两次写规范化代码,但是你需要处理不同的返回,因为你不想返回一个右值的引用。
如果你有类似的东西
static Vec3& normalize(Vec3& v) {/* normalize */ return v;}
static Vec3 normalize(Vec3&& v) { return normalize(v);}
^ v is a lvalue here
现在,您可以将tempoary转发到左值引用版本,然后按值返回,以便您不试图引用可能不再存在的对象。
不,你不能。 你必须使用两个版本。 您可以将它们组合为@NathanOliver建议,但您仍然需要两个版本。
我不明白为什么someFunc(const Vec3&v)会接受右值和左值,而非常量版本则不会。
因为标准禁止绑定右值到非const左值ref。 这和在同样的问题
const int& x = 1; // OK
int& y = 2; // error
看起来这个标准正试图保护你免受临时性的意外修改。 不幸的是,我不能给你更深入的解释。 但是你可以阅读这个:
为什么不是非const引用临时对象?
一个非const引用如何不能绑定到一个临时对象?
当然,最后&&
是为了允许而发明的。 所以我想它更像是一个历史原因?
上一篇: Can't make a function accept both rvalue and lvalue references