组合问题:运算符“==”和运算符“-”
combination issue : operator '==' and operator '-'
当我尝试编译这段代码时出现奇怪的错误。
我会解释我的问题。
我定义了一个 vector2D 如下:
typedef struct LX_Vector2D
{
float vx;
float vy;
LX_Vector2D& operator =(const LX_Vector2D v); // Defined
} LX_Vector2D;
我还在这个向量上定义了两个运算符:
bool operator ==(LX_Vector2D& u,LX_Vector2D& v); // Are u and v equal?
LX_Vector2D operator -(LX_Vector2D& u); // Get the opposite vector
定义了所有这些重载运算符。
所以我在下面的代码中测试了这些运算符:
LX_Vector2D u = {3.14,-2.56};
LX_Vector2D expected_vec = {-u.vx,-u.vy};
if(expected_vec == (-u)) // ERROR
cout << "OK" << endl;
else
cout << "NO" << endl;
当我编译这段代码时,我有这个错误:
'expected_vec == operator-((* & u))'[=15 中的'operator=='不匹配=]
我对“=”和“==”没有问题,因为我在实现“-”之前定义并测试了它们。
但是当我修改这段代码得到这个:
u = -u;
if(expected_vec == u) // OK
我没有错误。
我不明白,因为这两段代码在语义上似乎是相同的。
这里是运算符'-'的定义:
LX_Vector2D operator -(LX_Vector2D& u)
{
return {-u.vx,-u.vy};
}
所以我的问题是:
为什么我的编译器无法将 'expected_vec == (-u)' 识别为对 operator '==' 的调用expected_vec 和 (-u) 作为参数?
另一个问题:
如果可能的话,我怎么可能毫无问题地使用 if(expected_vec == (-u))?
我使用 g++ 4.6.1.
这里的问题是 operator-
用作另一个表达式的一部分时的结果是 临时 值,并且 operator==
接受非常量引用。非常量引用不能绑定到临时值。
简单的解决方案?使 operator==
函数采用常量引用:
bool operator ==(const LX_Vector2D& u, const LX_Vector2D& v)
// ^^^^^ ^^^^^
// Note the use of `const`
作为一般建议,在声明不会修改其参数的函数时,始终将参数作为常量传递。它将避免这样的问题,并且还可以帮助编译器进行可能的优化。
运算符-
returns一个临时对象:
LX_Vector2D operator -(LX_Vector2D& u)
而您的比较运算符接受非 const
引用:
bool operator ==(LX_Vector2D& u,LX_Vector2D& v)
临时对象,如 -
运算符返回的对象,不能用作非 const
引用。这是不允许的,因为修改即将超出范围的对象毫无意义,因此编译器确保您甚至不会尝试它。
作为一般规则,您应该让任何不修改其参数的函数采用 const
引用,尤其是比较函数:
bool operator ==(const LX_Vector2D& u,const LX_Vector2D& v)
除了其他答案之外,您的赋值运算符还应该采用 const&
,如:
LX_Vector2D& operator =(const LX_Vector2D& v)
注意参数类型后面的&
。
作为一般规则,为了避免构造不必要的对象副本,如果您不打算更改参数实例,复杂类型的参数几乎应该总是 const &
。或者,如果您打算更改参数实例,则仅作为参考,即 &
.
当我尝试编译这段代码时出现奇怪的错误。
我会解释我的问题。
我定义了一个 vector2D 如下:
typedef struct LX_Vector2D
{
float vx;
float vy;
LX_Vector2D& operator =(const LX_Vector2D v); // Defined
} LX_Vector2D;
我还在这个向量上定义了两个运算符:
bool operator ==(LX_Vector2D& u,LX_Vector2D& v); // Are u and v equal?
LX_Vector2D operator -(LX_Vector2D& u); // Get the opposite vector
定义了所有这些重载运算符。
所以我在下面的代码中测试了这些运算符:
LX_Vector2D u = {3.14,-2.56};
LX_Vector2D expected_vec = {-u.vx,-u.vy};
if(expected_vec == (-u)) // ERROR
cout << "OK" << endl;
else
cout << "NO" << endl;
当我编译这段代码时,我有这个错误:
'expected_vec == operator-((* & u))'[=15 中的'operator=='不匹配=]
我对“=”和“==”没有问题,因为我在实现“-”之前定义并测试了它们。
但是当我修改这段代码得到这个:
u = -u;
if(expected_vec == u) // OK
我没有错误。 我不明白,因为这两段代码在语义上似乎是相同的。
这里是运算符'-'的定义:
LX_Vector2D operator -(LX_Vector2D& u)
{
return {-u.vx,-u.vy};
}
所以我的问题是:
为什么我的编译器无法将 'expected_vec == (-u)' 识别为对 operator '==' 的调用expected_vec 和 (-u) 作为参数?
另一个问题:
如果可能的话,我怎么可能毫无问题地使用 if(expected_vec == (-u))?
我使用 g++ 4.6.1.
这里的问题是 operator-
用作另一个表达式的一部分时的结果是 临时 值,并且 operator==
接受非常量引用。非常量引用不能绑定到临时值。
简单的解决方案?使 operator==
函数采用常量引用:
bool operator ==(const LX_Vector2D& u, const LX_Vector2D& v)
// ^^^^^ ^^^^^
// Note the use of `const`
作为一般建议,在声明不会修改其参数的函数时,始终将参数作为常量传递。它将避免这样的问题,并且还可以帮助编译器进行可能的优化。
运算符-
returns一个临时对象:
LX_Vector2D operator -(LX_Vector2D& u)
而您的比较运算符接受非 const
引用:
bool operator ==(LX_Vector2D& u,LX_Vector2D& v)
临时对象,如 -
运算符返回的对象,不能用作非 const
引用。这是不允许的,因为修改即将超出范围的对象毫无意义,因此编译器确保您甚至不会尝试它。
作为一般规则,您应该让任何不修改其参数的函数采用 const
引用,尤其是比较函数:
bool operator ==(const LX_Vector2D& u,const LX_Vector2D& v)
除了其他答案之外,您的赋值运算符还应该采用 const&
,如:
LX_Vector2D& operator =(const LX_Vector2D& v)
注意参数类型后面的&
。
作为一般规则,为了避免构造不必要的对象副本,如果您不打算更改参数实例,复杂类型的参数几乎应该总是 const &
。或者,如果您打算更改参数实例,则仅作为参考,即 &
.