2010-10-28 16 views
12

tengo la siguiente funciónpasando una cadena literal a una función que toma un std :: string &

void AddNodeValue(XMLNode& node, std::string& value); 

quiero utilizar de esta manera:

document.AddNodeValue(modvalue,"modvalue"); 

y el compilador se queja:

error C2664: 'void XML::XMLDocument::AddNodeValue(XML::XMLNode &,std::string &)' : cannot convert parameter 2 from 'const char [9]' to 'std::string &' 
     A reference that is not to 'const' cannot be bound to a non-lvalue 

¿No entiendo por qué está mal?

Compilador: VS2003

Respuesta

23

Su función necesita tomar const std::string& para que lo use el estilo.

C++ tiene una regla según la cual un valor r (en su caso, un std::string temporal creado a partir del literal de cadena) puede vincularse con una referencia const, pero no con una referencia no constante.

Hasta donde yo sé, esta restricción no se debe a ningún problema fundamental de implementación, ya que los valores temporales pueden modificarse de otras maneras. Pero se supone que una función que toma una referencia no constante lo hace porque su objetivo principal es modificar ese argumento. Por lo general, no tiene mucho sentido hacer eso de forma temporal, por lo que posiblemente la prohibición atrape errores mucho más de lo que impide que las personas hagan algo que valga la pena. De todos modos, no todos los valores r son temporales: algunos son literales que realmente no se pueden modificar.

Si no puede cambiar el AddNodeValue función, entonces se puede trabajar alrededor de ella:

std::string valstr("modvalue"); 
document.AddNodeValue(modvalue, valstr); 
// valstr might have changed, check the documentation of AddNodeValue 
+0

La limitación existe básicamente para hacer cumplir la semántica de referencia. La referencia está destinada a ser utilizada con objetos válidos y persistentes. Claro que puede crear una referencia no válida devolviendo una referencia al valor local, pero ese es un error semántico. –

+1

@Let_Me_Be: right (asumiendo que por "referencia" se quiere decir "referencia no constante", obviamente las referencias const no se deben usar solo con objetos persistentes). La siguiente pregunta, entonces, es * por qué * las referencias no const están destinadas a ser usadas con objetos válidos y persistentes, y AFAIK es porque normalmente no tiene mucho sentido modificar objetos que no lo son. C++ 0x proporciona un nuevo tipo de referencia para objetos que son válidos pero no persistentes, lo que es bueno para las ocasiones en las que tiene sentido modificar dichos objetos. –

+0

Sí, C++ 0x proporciona referencias l-value. El punto de referencia completo (internamente sigue siendo un puntero) es que está muy limitado (al estar vinculado a un objeto existente, no nulo, etc.). Por lo tanto, el compilador puede proporcionar optimizaciones mucho más interesantes. –

Cuestiones relacionadas