Error when Initialising a reference to a pointer to const string with pointer to a non-const string

Viewed 72

Hi i am trying to understand how references and pointers work in C++ and so was trying out different examples, in one of which i am unable to understand why the error is produces:

int main()
{
     cout << "Hello World" << endl; 
     std::string s="hg";
     std::string *ptr=&s; 
     const std::string * &k=ptr ;
     return 0;
}

When compiling this program i am getting an error as:

error: cannot bind non-const lvalue reference of type ‘const string*& {aka const std::__cxx11::basic_string&}’ to an rvalue of type ‘const string* {aka const std::__cxx11::basic_string}’

My questions are as follows:

  1. Why in the quoted error it is written rvalue of type const string*. Which part is the rvalue here. The right hand side is a pointer ptr which is an lvalue.
  2. If we remove the const from infront of std::string so that the statement now becomes: std::string* &k=ptr the program works fine which i think is because now the type of both left hand side and right hand side are same. That is the referred to object type and the reference type is same after we remove the const.
  3. Now i tried a different statement as follows: std::string* const& = ptr; and it turns out this also works. So my question is why in this case the code works but in the first case(when const was in front) it did not work? PS: I know in the statement: const std::string * &k = ptr ; k is a reference to a pointer to const string while in the statement std::string* const&k = ptr; k is a reference to a const pointer. But why in one case it works and in another it doesn't?
  4. Now if i add change the statement to const std::string* const&k = ptr; the program works again. How is the program working for this case.
1 Answers
  1. Given const std::string * &k=ptr ;, as you've seen, types don't match here. You're trying to bind a std::string* to reference to const std::string*. References can't bind to objects with different type directly, std::string* needs to be converted to const std::string*, which is a temporary, i.e. an rvalue, then you got the error that rvalue can't be bound to reference to lvalue.

  2. std::string * &k=ptr ; works because types match and no conversion is required.

  3. std::string* const& k= ptr; works as #2, except that k is a lvalue-reference to const which can't be modified.

  4. const std::string* const&k = ptr; works because k is a lvalue-reference to const, which could bind to temporary const std::string* converted from std::string*. (BTW rvalue-reference works too. e.g. const std::string* &&k = ptr;)

Related