2017-06-01 74 views
1
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

回答

8

你可以用一點點的開銷來做到這一點。你不必兩次寫規範化代碼,但是你需要處理不同的返回,因爲你不想返回一個右值的引用。

如果你有這樣的事情

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

現在您可以tempoary轉發到左值的參考版本,然後通過返回值,這樣你是不是想指那些不再存在的對象。

1

沒有,你可以「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?

當然在最後&&的發明正是爲允許。所以我想它更像是一個歷史原因?

相關問題