3

私は、すでに win32 で動作している Android 用の 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は上記で宣言されたクラスです。その宣言は次のとおりです。

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;
};

このクラスの定義は、適切ではないため、ここには記載しません。

しかし、残念ながら私はエラーを受け取ります:

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;

コンパイル中にエラーが発生することはありません。このばかげたエラーの原因がわかりません。この問題を解決する方法を教えていただければ幸いです。

4

2 に答える 2

3

r-valueconst 以外の参照にバインドすることはできません。

この行:

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

は次と同等です: (PARAMS例を読みやすくするために、パラメーターを次のように置き換えました):

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

ここでVector2(PARAMS)は、一時オブジェクトを作成します。つまり、演算子のオーバーロードに右辺値参照を渡そうとしていますが、演算子が次のように宣言されているため、コンパイラは一致を見つけられません。

Vector2 operator+ (Vector2& vector);

一時オブジェクトを非 const 参照にバインドできない理由の詳細については、これを参照してください:非 const 参照が一時オブジェクトにバインドできないのはなぜですか?

2 番目の例Vector2では、最初に 2 つのオブジェクトを宣言してから、演算子のオーバーロードに一致する左辺値参照として演算子に渡します。

この問題を解決し、演算子のオーバーロードが左辺値と右辺値の両方の参照を取得できるようにする 1 つの方法は、右辺const値を への参照にバインドしてもまったく問題ないため、への参照を取得すると宣言すること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.
于 2013-08-25T22:34:41.167 に答える
2

非 const 参照として一時オブジェクトを渡そうとしています。operator +const 参照を取るように署名を変更します。

Vector2 operator + (const Vector2 & vector);

2 番目のサンプルが機能する理由は、Vector2 オブジェクトに名前を付けているためです。それらはもはや一時的なものではありません。

于 2013-08-25T21:35:50.293 に答える