不能让一个函数同时接受右值和左值引用

问题描述:

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)都接受右值和左值而非常量的版本则没有。)

+1

这可能会解释为什么临时可以绑定到const引用的一些混淆:https://stackoverflow.com/questions/36102728/why-is-it-allowed-to-pass-r-values-by-const引用的但不按正常refrence – NathanOliver

你可以用一点点的开销来做到这一点。你不必两次写规范化代码,但是你需要处理不同的返回,因为你不想返回一个右值的引用。

如果你有这样的事情

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?

当然在最后&&的发明正是为允许。所以我想它更像是一个历史原因?