1. The fact that a link cannot be initialized with a value instead of another variable is understandable and logical, but how is it that if you specify the link as const, then it becomes possible to initialize it with a value?

const std::string& s = "String"; 

2. If you return a variable from a function, then why in the same place this variable can not be assigned a value? How does it turn out that returning a variable by reference makes it possible to assign values ​​to the returned variables?

 #include <iostream> #include <string> std::string f(std::string& s) { return s; } int main() { std::string s = "string"; f(s) = "another string"; std::cout << s << std::endl; } 

The top code at the place where the function is used should generally look like this, s = "another string"; , but the output "string" instead of "another string" looks strange to me. Could you clarify for me these details?

  • And what has become possible to assign? ideone.com/0hjYC1 - Qwertiy
  • So give the complete code example in ideone. - Qwertiy
  • Do not assign and initialize, confused a little. This is a complete code example. - nammidd
  • Completed the answer. - Qwertiy
  • If the code from the question you output "another string", then throw out the compiler that you are using, because this is absolutely not true. Must output "string". - ixSci

3 answers 3

  1. You can assign a value, but not a link, but a variable to which it refers.

    A link without const refers to a variable object, respectively, it must be a variable or something similar. When trying to initialize a link using rvalue, a compilation error occurs. A constant reference may well refer to an immutable object, which is the rvalue value. You could also use a special rvalue link: std::string &&s = "String"; .

  2. It does not change anything. It was possible - and it was possible, it was impossible - and it was impossible.

  3. In order to be "another string" , you lost the return link:

     std::string &f(std::string& s) // ^-------------------- в твоём коде этого нет 
  • 3. I have not lost anything, this is my question why I cannot technically assign the value of the returned variable, but should return by reference. - nammidd
  • Because you do not return a variable, but a copy. And the class has an overloaded assignment operator. And the variable was assigned nothing - assigned to the junk temporary line. - Qwertiy
  • I tried to google, but I still did not understand why I did not return a variable, but a copy? - nammidd
  • @nammidd, because you do NOT return the link. So you are returning a copy. - Qwertiy
  1. The fact that a link cannot be assigned a value is understandable and logical, but how is it that if you specify a link as const, then it becomes possible for it to assign a value?

    Because "String" is an array of const char[] , and your link requires std::string . Due to the inconsistency of the types, the compiler cannot directly perform the assignment, but instead generates the creation of an instance of std::string with a call to the constructor std::string::string(const char*) , because it is non-trivial.

    And then there is a bad question. The link does not store anything in itself; it points to another object in another variable. And there is no variable. And where then to store this std::string ? And it is necessary to store explicitly, because it can later be changed through a link.

    But as soon as you make the link constant, ...

    And no. The reason is simple - the committee made an exception to the rule :

    Normally, it is a temporary object lasts only. However, the C ++ doesn’t have a common dangling-reference error.

    Transfer:

    As a rule, a temporary object lives until the end of the expression in which it was created. However, C ++ deliberately indicates that assigning a temporary object to a reference to const extends the lifetime of the object to the lifetime of this link, thus avoiding the problem of hanging links.

  2. If you return a variable from a function, then why in the same place this variable can not be assigned a value?

    Because the function returned a copy of the object. You can do anything with it, but as soon as the action of the line is completed, this copy will be destroyed if you do not extend its lifetime by assigning it to a variable.

  3. How does it turn out that returning a variable by reference makes it possible to assign values ​​to the returned variables?

    Well, this is a link, that is, the same pointer. The link points to the original object, giving the opportunity to see him wield.

    1. Links in C ++ are not only possible, but often need to be assigned values. At the same time, you need to understand that by assigning a new value to a link, you are in fact assigning a new value to the variable to which this link refers:

       int a = 1; int& b = a; // b - ссылка на a b = 2; // здесь изменится значение a cout << a << endl; // выведет 2! 

      Passing arguments to a function by reference has 2 goals:

      Avoid creating a copy of a variable (if the variable is a heavy object with "expensive" copying). If it does not intend to change this variable inside the function, it should be passed via a constant reference.

      If the variable really needs to be changed inside the function. In this case, you cannot use a constant link:

       int foo(const int& a, int& b string& failure_reason) { ... b++; a++; // ошибка, не компилируется ... if (something_wrong) { failure_reason = "why error occured" return 1 } else { failure_reason = ""; return 0 } } ... int a = 1, b = 2; string s; if (foo(a, b, s)) { cout << "error: " << s << endl; } cout << b << endl; // 3</pre> 
    2. When returning a variable from a function by reference, it is just possible to assign a value to it:

       int& foo() { static int a = 0; return a; } foo() = 1; cout << foo() << endl; 

      Note that returning a local variable reference from a function is an undefined behavior, since when exiting the function (scope), the variable is destroyed and your link will refer to the remote object:

       int& foo() { int a = 0; return a; // скомпилируется, но работать не будет }