I stumbled upon the fact that one can't bind a temporary variable to a reference unless it is a constant and found it to be indeed true in the given code. However, i am not able to find out the difference in my other code snippet where I didn't use const reference but it still work. I couldn't get my head around it.
This is the code where I seek help.

#include <iostream>
#include <sstream>
using namespace std;

void replace(string& str, int length)
{}

int main()
{
    try
    {
        string str="nabh nchy 13 raghav                  ";     //to share the string use std::shared_ptr<std::string> var1 = std::make_shared<std::string>();
        replace(str, 19);
        cout<<str<<endl;
    }
    catch(exception& e)
    {
        cout << "Standard exception: "<<e.what()<<endl;
    }
}

Isn't str in the above code temporary. If not, kindly clarify the difference between them.
This is the code where I tried to bind temporary with the reference.
And this is the error which I get if reference on line 16 isn't constant.
gotcha.cpp:24:9: error: invalid initialization of non-const reference of type ‘MyString&’ from an rvalue of type ‘int’

#include <iostream>
#include <string>
using namespace std;

class MyString
{
    public:
    MyString(int size):str(size, ' ')
    {
    }

//  private:
    string str;
};

void print(const MyString& mystr)   //error reference needs to be const
{
    cout<<mystr.str;
}

int main()
{
    int a=3;
    print(a);
}

As a rule of thumb, a temporary object has no name and you can't get its address. So the string named str is not temporary; it has a name.

In your second code, it looks like you've got an int object and you're trying to pass it to a function that expects a reference to a MyString object.

Edited 3 Years Ago by Moschops

When it's considered to be temporary? Why a's content isn't in memory address?As far as scope is concerned, scope of both is in main().

Here's a simple example.

int c = a + b;

Some value a+b is created before that value is assigned to c. It has no name. You can't get it's address.

What's actually wrong with your second code? It compiles fine, and doesn't compile if you take out the const.

Edited 3 Years Ago by Moschops

But doesn't c's memory address contain value of a+b? if so, why a's address can't be accessed? Isn't supposed to store 3?

int c = a + b;

First, a value is calculated. Computers work slowly. First the value of a+b has to be calculated and stored somewhere, and then we can set c to that value. So first, the value of a+b is calculated. This is put somewhere. It has no name. You can't get its memory address. Is this c? No. We have not yet done anything to c. But a+b has been calculated, and stored somewhere in memory. Does it have a name? Can you get to it? No.

if so, why a's address can't be accessed?
What are you talking about? You can get a. You can get its memory address.

 int a=3;
 // What is a?
 cout << a; // We CAN get a
 // What is a's memory address?
 cout << &a; // We CAN get a's memory address.

Edited 3 Years Ago by Moschops

But doesn't c's memory address contain value of a+b?

Yes, after it has been assigned. A better example might be f(a+b) where f takes an int reference. Since the result of a+b is a temporary without an address, the call is illegal, but c=a+b; f(c); would be fine because c is a variable.

if so, why a's address can't be accessed? Isn't supposed to store 3?

It can. But what you're passing to print isn't a. It couldn't possibly be because print wants a MyString, not an int. So what you're passing to print is the result of MyString(a) (which is implicitly applied because it isn't marked explicit). And that result is a temporary object that's not stored in a variable and doesn't have an address. If you store it in a variable first, there will be no problem:

MyString a_as_string(a);
print(a_as_string); // Works fine even with a non-const reference

That said, print really should take a const reference because it doesn't modify its argument and there is thus no reason for it to take a non-const reference.

Also your MyString constructor really should be explicit because it makes no sense for an integer n to be implicitly converted to an empty string of size n.

Edited 3 Years Ago by sepp2k

It was really well explained. Thanks sepp2k for reply.

This question has already been answered. Start a new discussion instead.