2013-08-25 86 views
3

我想爲android構建一些C++代碼,已經在win32上工作。我有一個問題,運營商負擔過重。例如:C++編譯錯誤,無法匹配運算符

代碼:

Vector2 uv0 = textures.back()->m_uv0; 
Vector2 uvt = textures.back()->m_uvt; 

uv0 = m_uv0 + Vector2(uv0.x * m_uvt.x, uv0.y * m_uvt.y) + Vector2(0.01f,0.01f); 

Vector2高於declarated一個類。它的聲明是:

class Vector2 
{ 
public: 
//Constructors 
Vector2() : x(0.0f), y(0.0f){} 
Vector2(GLfloat _x, GLfloat _y) : x(_x), y(_y) {} 
Vector2(double _x, double _y) : x(static_cast<float>(_x)), y(static_cast<float>(_y)) {} 
Vector2(int _x, double _y) : x(static_cast<float>(_x)), y(static_cast<float>(_y)) {} 
Vector2(double _x, int _y) : x(static_cast<float>(_x)), y(static_cast<float>(_y)) {} 
Vector2(int _x, int _y) : x(static_cast<float>(_x)), y(static_cast<float>(_y)) {} 
Vector2(GLfloat * pArg) : x(pArg[0]), y(pArg[1]) {} 
Vector2(const Vector2 & vector) : x(vector.x), y(vector.y) {} 

//Vector's operations 
GLfloat Length(); 
Vector2 & Normalize(); 
Vector2 operator + (Vector2 & vector); 
Vector2 & operator += (Vector2 & vector); 
Vector2 operator -(); 
Vector2 operator - (Vector2 & vector); 
Vector2 & operator -= (Vector2 & vector); 
Vector2 operator * (GLfloat k); 
Vector2 & operator *= (GLfloat k); 
Vector2 operator/(GLfloat k); 
Vector2 & operator /= (GLfloat k); 
Vector2 & operator = (Vector2 vector); 
Vector2 Modulate(Vector2 & vector); 
GLfloat Dot(Vector2 & vector); 
void Set(GLfloat _x, GLfloat _y); 

//access to elements 
GLfloat operator [] (unsigned int idx); 

//data members 
float x; 
float y; 
}; 

這個類的定義我不會在這裏列出,因爲它沒有metter。

但不幸的是我recive一個錯誤:

G:/PROJECT266/projects/PROJECT266//jni/../jni/SBE/source/Sprite.cpp: In member function'void Sprite::AddTex(TEX::GUItex)': 
G:/PROJECT266/projects/PROJECT266//jni/../jni/SBE/source/Sprite.cpp:103:57: error: no match for 'operator+' in '((Sprite*)this)->Sprite::m_uv0 + Vector2((uv0.Vector2::x *((Sprite*)this)->Sprite::m_uvt.Vector2::x), (uv0.Vector2::y * ((Sprite*)this)->Sprite::m_uvt.Vector2::y))' 
G:/PROJECT266/projects/PROJECT266//jni/../jni/SBE/source/Sprite.cpp:103:57: note: candidates are: 
G:/PROJECT266/projects/PROJECT266//jni/../jni/SBE/source/SBMath.h:38:10: note: Vector2 Vector2::operator+(Vector2&) 
G:/PROJECT266/projects/PROJECT266//jni/../jni/SBE/source/SBMath.h:38:10: note: no known conversion for argument 1 from 'Vector2' to 'Vector2&' 

但是,如果我重寫上面的代碼是這樣的:

Vector2 uv0 = textures.back()->m_uv0; 
Vector2 uvt = textures.back()->m_uvt; 

Vector2 vec1 = Vector2(uv0.x * m_uvt.x, uv0.y * m_uvt.y); 
Vector2 vec2 = Vector2(0.01f,0.01f); 

uv0 = m_uv0 + vec1 + vec2; 

世上本沒有編譯過程中的任何錯誤。 我不明白,這個愚蠢的錯誤是什麼原因造成的。 如果你向我解釋如何解決這個問題,我會很高興。

+0

是您在Win32平臺上使用的是什麼編譯器?接受該代碼是錯誤的。 – aschepler

+0

@aschepler不幸的MSVC從標準的流浪...如果它允許這樣我不會感到驚訝:/ – krsteeve

+0

一些頁面顯示這是在MSVC 2003中修復的。我只是想知道什麼版本。 – aschepler

回答

3

無法將的r值綁定到非const參考

這條線:

uv0 = m_uv0 + Vector2(uv0.x * m_uvt.x, uv0.y * m_uvt.y) + Vector2(0.01f,0.01f); 

等效於:(I替換的參數與PARAMS使我的例子更易讀):

uv0 = (m_uv0.operator+(Vector2(PARAMS))).operator+(Vector2(PARAMS)); 

這裏Vector2(PARAMS)將創建臨時對象。這是您要的R值引用傳遞到您的運算符重載和您的運營商被聲明爲編譯器不會找到一個匹配:

Vector2 operator+ (Vector2& vector); 

有關的臨時爲什麼不能勢必更多信息非const引用看到這一點:How come a non-const reference cannot bind to a temporary object?

在第二個例子首先聲明兩個Vector2對象,然後將它們傳遞給操作升價值,你的運算符重載匹配引用。

解決此問題並讓操作符重載同時使用l值和r值引用的一種方法是將其聲明爲參考const,因爲將r值綁定到引用可以完全正確const。請參閱krsteeve的回答,瞭解如何完成此操作。

一般而言,如果您不打算修改參數,通常應該聲明引用參考的函數作爲參考const。參考

實例綁定:

Vector2& ref1 = Vector2(); // Error, trying to bind r-value to non-const ref. 
Vector2 v; 
Vector2& ref2 = v; // OK, v is an l-value reference. 

// It is however OK to bind an r-value to a const reference: 
const Vector& ref3 = Vector2(); // OK. 
2

您試圖將臨時對象作爲非常量引用傳遞。更改operator +的簽名採取一個const引用:

Vector2 operator + (const Vector2 & vector); 

你的第二個樣品成功運作的原因是,你現在命名Vector2對象,他們不再是暫時的。

+1

第一個操作數應該也可以允許'const'。 – aschepler

+0

@aschepler代碼示例應該用const來散佈。 – krsteeve