string &str and string &&str

I want to clarify to see if I have the concept of L&R value referencing correct.

1
2
3
4
5
6
7
string str = "Hello";
// The address of rStr is equal to the address of str
string &rStr = str;
rStr+=" World";
// They would both be equal, since rStr has the same address of str
// Therefore any chances made from one string would affect the other
cout << (rStr == str);


Lvalue referencing only allows the string to be initialized as another value and cannot be initialized like a regular string.

1
2
3
string str = "Hello";
string &str2 = str; // Correct
string &str3 = "Hello World"; // Incorrect 


I am a bit confused on the use of double '&'

1
2
3
string str = "Hello";
string &&str1 = " World"; // Correct
string &&str2 = str + str1; // Correct 


Are the double '&' the same as dereferencing? (like in pointers cout << *p)
The double '&' works the same way as declaring and initializing a regular string, so why would it be useful?

I am trying to figure out why using &str and &&str is useful, since we can just do without it.
Regular references (l-value references) is mainly useful when passing arguments to functions. If you don't use references the function will receive copies of the arguments. This is fine for simple types such as int or bool, but for class types like std::string it would be wasteful to create copies if it wasn't necessary. You can also use references if you want the function to modify the variables that was passed to the function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

// The name will be passed by non-const reference to allow the
// function to modify the string variable that was passed in.
void read_name(std::string& name)
{
	std::cout << "Enter your name: ";
	std::cin >> name;
}

// The name is passed by const reference to avoid creating 
// unnecessary copies of the string.
void print_name(const std::string& name)
{
	std::cout << "Your name is " << name << ".\n";
}

int main()
{
	std::string name;
	read_name(name);
	print_name(name);
}



string&& is an r-value reference that can refer to temporary objects (unnamed objects that are about to be destroyed). It's seldom necessary, but they can be used to make code more efficient.

For example, in the following statement:

 
str2 = str + str1;

(str + str1) will create a temporary object that will be destroyed at the end of the line.

In old C++, before r-value references, str2 would simply copy the content of the temporary object.

In new C++ std::string has an assignment operator that accepts a std::string&& which will be used instead. It is perfectly safe to "steal" the content of the r-value reference because no one will ever notice if the temporary object is modified, it's going to be destroyed anyway. So thanks to r-value references it only needs to set some pointers instead of copying all character data.


It's possible to turn regular variables into r-value references by using std::move. This can be useful where you want to copy a variable but don't really care what value the variable has afterward. This is often refereed to as moving, to distinguish it from regular copying.

1
2
3
4
5
6
7
8
9
10
11
12
std::vector<std::string> names;

std::string name;
while (read_name(name), name != "quit")
{
	// The name is efficiently moved (not copied) to the end of the vector.
	names.push_back(std::move(name));

	// If you print name here you don't know what you'll get. Probably an 
	// empty string, but the C++ standard says the value is "unspecified".

}

Last edited on
Topic archived. No new replies allowed.