Su opción más inteligente es que sea una función amigo.
Como mencionó JaredPar, la implementación global no puede acceder a miembros protegidos y privados de la clase, pero también hay un problema con la función miembro.
C++ permitirá las conversiones implícitas de los parámetros de la función, pero no una conversión implícita de this
.
Si existen tipos que se pueden convertir a la clase X:
class Y
{
public:
operator X(); // Y objects may be converted to X
};
X x1, x2;
Y y1, y2;
Sólo algunas de las siguientes expresiones compilará con una función miembro.
x1 == x2; // Compiles with both implementations
x1 == y1; // Compiles with both implementations
y1 == x1; // ERROR! Member function can't convert this to type X
y1 == y2; // ERROR! Member function can't convert this to type X
La solución, para obtener lo mejor de ambos mundos, es implementar esto como un amigo:
class X
{
int value;
public:
friend bool operator==(X& left, X& right)
{
return left.value == right.value;
};
};
Es una buena práctica para declarar argumentos no sólo de referencia, pero también const, siempre que estés seguro de que puedes. Los operadores de comparación pueden ser const y tomar referencias const seguramente. (Si nada más, es una promesa para el compilador que le permite hacer más optimizaciones). –