不能让一个函数同时接受右值和左值引用
问题描述:
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
的两个版本吗?
(我感到困惑右值VS左值的引用,我并不例如明白为什么someFunc(const Vec3& v)
都接受右值和左值而非常量的版本则没有。)
答
你可以用一点点的开销来做到这一点。你不必两次写规范化代码,但是你需要处理不同的返回,因为你不想返回一个右值的引用。
如果你有这样的事情
static Vec3& normalize(Vec3& v) {/* normalize */ return v;}
static Vec3 normalize(Vec3&& v) { return normalize(v);}
^v is a lvalue here
现在您可以tempoary转发到左值的参考版本,然后通过返回值,这样你是不是想指那些不再存在的对象。
答
没有,你可以“T。你必须使用两个版本。您可以将它们组合为@NathanOliver建议,但您仍然需要两个版本。
我不例如明白为什么someFunc(常量VEC 3 & V)将接受而非常量的版本将不能同时右值和左值。
由于标准禁止结合右值到非const左值REF。这是相同的问题
const int& x = 1; // OK
int& y = 2; // error
看来,标准是试图保护你的临时的意外修改。不幸的是,我不能给你更深入的解释。但是你可以看到这一点:
Why not non-const reference to temporary objects?
How come a non-const reference cannot bind to a temporary object?
当然在最后&&
的发明正是为允许。所以我想它更像是一个历史原因?
这可能会解释为什么临时可以绑定到const引用的一些混淆:https://stackoverflow.com/questions/36102728/why-is-it-allowed-to-pass-r-values-by-const引用的但不按正常refrence – NathanOliver