2012-03-08 7 views
5

Cuando intento compilar el siguiente en ideone:¿Por qué es + = temporales válidos en la biblioteca estándar?

class X 
{ 
    public: 
    friend X& operator+=(X& x, const X& y); 
}; 

X& operator+=(X& x, const X& y) { return x; } 

int main() 
{ 
    X() += X(); 
} 

Como era de esperar, esto arroja un error de compilación, porque no se puede pasar una temporal a una referencia no const.

Sin embargo, la siguiente compila con éxito en ideone:

std::string() += std::string(); 

No debería este error como mi ejemplo anterior?

Editar:

Si std :: string() define como una operación += miembro, ¿por qué hacer esto cuando tal uso permite que el lado izquierdo sea un temporal? ¿Por qué no definirlo como lo he mencionado anteriormente y evitar la referencia a problemas temporales?

+0

para el registro, ambos compilan en VC++ 10.0 con advertencia 'advertencia C4239: extensión no estándar utilizada: 'argumento': conversión de 'X' a 'X &' ' –

+1

@DougT.: VS permite vincular las temperaturas a referencias no constantes como una extensión, por lo que no es una cadena de herramientas útil para probar esto en –

+1

-1 para cambiar radicalmente la pregunta después de haber sido respondida. No genial. Si tiene seguimientos, formule una pregunta por separado, no secuestrar su propia pregunta para preguntar algo completamente diferente una vez que se haya respondido el original. – littleadv

Respuesta

6

La regla C++ es que no se puede obligar a un temporal a una referencia no const. Sin embargo, puede llamar a funciones temporales no constantes: si define operator +=() como miembro, puede llamarlo a su objeto. Este es uno de los trucos para obtener una referencia temporal, p. Ej. cuando se utiliza un temporal std::istringstream para leer un tipo no básico (tipos básicos son leídos por los miembros):

std::string word; 
if (std::istringstream("hello world") >> std::ws >> word) { ... } 

(sí, esto es un ejemplo tonto).

3

Porque es esconst.

string::operator+=

cambiar a X& operator+=(const X& y) hará que su código de compilarse bien igual de bien.

edición

ha cambiado la pregunta después de haber respondido ya y le cambió la definición de su X::operator+= a ser una función friend en lugar de una función miembro. Eso sería realmente no trabajo. Tenga en cuenta que std::string::operator+= no es friend, es una función miembro de std::string.

+0

Vaya, ahora he modificado la pregunta. ¿Por qué no la biblioteca estándar define operator + = como lo hice anteriormente? – Clinton

+0

bien, probablemente para permitir "x + = cadena (" y ");" para trabajar, por ejemplo. No veo ninguna razón por la que no debería permitir eso. Si solo necesita convertir algún tipo en std :: string para agregarlo a otra cadena, ¿por qué no hacerlo de esta manera? – littleadv

+0

No estoy seguro de lo que quiere decir "allow' x + = string ("y"); 'para el trabajo. El ejemplo que doy permite' x + = string ("y"); ', pero no permite' string ("x") + = string ("y") '. – Clinton

3
string& operator+= (const string& str); 

sentir la diferencia

0

operator+= está generalmente sobrecargado como una función miembro, y funciones miembro (const o de otro tipo) puede ser llamados temporales rvalues ​​.

Si cambia su sobrecarga a un miembro, X& operator+=(const X&), entonces su ejemplo también debería compilarse.

Cuestiones relacionadas