views:

222

answers:

4
void outputString(const string &ss) {
    cout << "outputString(const string& ) " + ss << endl;
}

int main(void) {
    outputString("constant tranformed to reference argument");
    //! outputString(new string("abc")); new only return pointer to object
    return 0;
}

Since its prohibited to create temporary object reference transforming to methods,this syntax should be useless but even make things more confusing.So why do C++ bother to support this kind of syntax?

EDIT:To be honest,I didn't understand your representation.Considering the above example,we would normally use void outputString(const string ss) instead of void outputString(const string &ss).I think the normal thing is 'pass by value' methods deal with the constants/variables and 'pass by reference' methods deal with variables only.The only reason we should use const type-id & instead of const type-id for constants is efficiency because 'pass by reference' methods only take the pointers(addresses) of the primitives constants/objects variables but 'pass by value' methods need to do the copy.

thanks.

+3  A: 

Where are you modifying ss?

cout << "outputString(const string& ) " + ss << endl;

This line creates a temporary under the hood *without* modifying the const& object ss.

The compiler will typically do:

string tmp = "outputString(const string& ) " + ss;
cout << tmp << endl;
dirkgently
+3  A: 

It is only allowed to create a temporary reference for const parameters. If the parameter was not a const reference then you could alter the data in the method not realising that your reference was to a temporary copy of the data and so it's prohibited.

When it's a const reference though, you can't alter the data so it doesn't matter that it's a reference to a copy and so safe, and therefore allowed as it's useful as your example shows.

John Burton
A: 

You mean, it allows literals to be transformed to a const object reference.

This is important. Otherwise you would have to write OutputString(std::string("literal")) and it would be very annoying. One would find himself making separate overloads for a method accepting std::string and char*.

Pavel Radzivilovsky
No, the literal is implicitly casted to a temporary std::string. That temporary is then passed as a const reference.
drspod
+1  A: 

What are your alternatives?

void outputString(const string ss);

That will create a copy of any string passed, even if the type matches exactly: Overhead that's not really needed!

void outputString(string &ss);

That will allow changing the passed argument. We don't want to do that, and C++ does not allow us to pass a temporary anymore, to protect us from changing a temporary (where those changes are lost in the next moments anyway).

So, the way you have it fits on two sides: It allows us to pass non-temporary strings without copying them, and it allows us to pass temporary strings. And it protects us from trying to change the argument. Seems like a good compromise.

Johannes Schaub - litb
but for temporary strings,there are no differences.
Jichao
Johannes Schaub - litb