Search code examples
c++stringreferencestring-literalsconst-reference

Why can a const reference to a string parameter take string literals?


Why can a const reference to a string parameter take string literals? String literals, like "hello", are not variables, so why is this code valid?

class CVector {
    public:
        int x, y;
        CVector() {};
        ~CVector() { delete ptr; }
        string* ptr;
        void doSomething(const string& str) { ptr = new string(str); }
        void print() { cout << "\n" << *ptr; }
};
int main()
{
    result.doSomething("asdas");
    result.print();
    return 0;
}

First of all, I thought that references as parameters were used to avoid the copying process and directly access the variable taken as argument(I could still be correct though). But the string literal "asdas" is not a variable, so why can the parameter take string literals as argument? I mean since the parameter str is a reference, it will become an alias for that entity, right? If so, did the literal just become a variable?

Shouldn't the parameter list consist of string& str instead of the const reference, so that the literal would be used in the construction of str?

And doesn't a const reference keep the referenced entity alive for as long as the reference is alive? If so, why would you do that to a literal?


Solution

  • When you do

    result.doSomething("asdas");
    

    The compiler looks to see if you have a doSomething(const char[]); and finds nothing. Since there is not suitable function it then tries to find an overload that takes something that can be constructed from a const char[] and it finds doSomething(const string& str). Since the compiler is allowed to make one user defined conversion it constructs a temporary std::string from the string literal and pass that temporary, via reference to const, to the function.

    Shouldn't the parameter list consist of string& str instead of the const reference, so that the literal would be used in the construction of str?

    No, this only works with a reference to const and will not work with a regular reference as regular references cannot bind to temporaries.

    And doesn't a const reference keep the referenced entity alive for as long as the reference is alive? If so, why would you do that to a literal?

    The reference to const will extend the lifetime of the object only when it is a function local object. Inside the scope of the function the object will be alive as the expression that called that function has not ended but if you were to try and keep a reference to the std::string in the class that would not work.

    Effectively you code is translated into

    int main()
    {
        CVector result
        {
            std::string temp = "asdas";
            result.doSomething(temp);
        }
        result.print();
        return 0;
    }