Cant pass a std string by reference ???

Jun 24, 2011 at 12:53pm
I have a classA with a simple method that returns a std string:
1
2
3
4
5
6
7
std::string classA::cadena()  {
    return "hello";
}

Into class B I have
void classB::writeS(std::string & value) {
}


Ok, i'm unable to write this

myclassB.writeS(myclassA.cadena());

When compile I have :
: error: no matching function for call to 'writeS(std::string)'
: note: candidate is: void Una::writeS(std::string&)



And If I do this :
1
2
3
 std::string mystring;
 mystring=classA.cadena();
 myclassB.writeS(mystring);

it works !.....

????

Any help ? Thanks
Jun 24, 2011 at 1:20pm
myclassB.writeS(myclassA.cadena());

The following is a train of thought; I do not offer this as an authoritative answer, as I'd have to dig out the standard and check the rules and so forth regarding temporary variables.

When you do this, myclassA.cadena() returns a temporary variable that has no name. If you were passing by value, a copy of it would be made and passed into writeS, so no problem. However, you're trying to pass by reference a temporary variable with no name. A reference is essentially an alias for something; it's just another name for a variable.

I'm not sure of the exact internal workings, but I'm not surprised it doesn't work.
Last edited on Jun 24, 2011 at 1:22pm
Jun 24, 2011 at 1:56pm
It should work with a temporary object because the temp object should be destroyed only after the function call that uses it is complete. I was also unaware that you could return a C string and compilers would change that to a std::string automatically. If you change cadena() to return std::string("hello");, does it make any difference?
Jun 24, 2011 at 2:00pm
It should work with a temporary object because the temp object should be destroyed only after the function call that uses it is complete.


Not saying you're wrong; more thinking out loud. How do you reference an object with no name? I really don't know enough about the reference mechanism to know if it can be done or not. I've always thought of a reference essentially as an alias, another name for something that already has a name.

Thinking out loud again, at a tangent,
"hello"
is a different kettle again, as it is a string literal and exists for the lifetime of the program, from start to finish.
"hello"
exists essentially forever, but the std::string created from it is temporary.
Last edited on Jun 24, 2011 at 2:02pm
Jun 24, 2011 at 2:01pm
The name is not important. Names are useless in a compiled program. Names are just for humans reading the code.
Jun 24, 2011 at 2:07pm
http://ideone.com/cEqgv

I got in trouble the first time I tried it, but I solved the problem by making UseString()'s only parameter const. Maybe all that is needed is to make it const.

I'll clone it change MyString() the way I suggested above and test.
Last edited on Jun 24, 2011 at 2:10pm
Jun 24, 2011 at 2:08pm
You know, I should have just looked this up from the start.

It's simply forbidden in (at least some) compilers to bind a non-const reference to a temporary. I'm rooting around for a reason in the standard...

Last edited on Jun 24, 2011 at 2:09pm
Jun 24, 2011 at 2:09pm
Nope, same error as before. See http://ideone.com/9bUdX . So it appears that in order to receive a temporary object, the parameter must be const.
Jun 24, 2011 at 2:17pm
http://www.cplusplus.com/articles/y8hv0pDG/

Why is this so important? There is a small clause in the C++ standard that says that non-const references cannot bind to temporary objects.


Can't find it myself, but clearly someone has. It's simply forbidden.

Edit:

Aha.
C++ 03 Section 8.5.3
refers.

...Otherwise, the reference shall be to a non-volatile const type
Last edited on Jun 24, 2011 at 2:22pm
Jun 24, 2011 at 2:30pm
Cool. So now it is crystal clear.
Jun 24, 2011 at 6:02pm
Incredible...... Thanks

Can anyone look at my last terrible problem ?
(Cant write a stream buffer to binary file ..)
Last edited on Jun 24, 2011 at 6:04pm
Topic archived. No new replies allowed.