
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Double Address Operator and & in C++
&& is a new reference operator defined in the C++11 standard. int&& a means "a" is an r-value reference. && is normally only used to declare a parameter of a function. And it only takes an r-value expression.
Simply put, an r-value is a value that doesn't have a memory address. E.g., the number 6 and character 'v' are both r-values. int a, a is an l-value, however, (a+2) is an r-value.
Example
#include <iostream> using namespace std; void foo(int&& a) { cout << "Value received: " << a << endl; } int main() { int b = 10; // foo(b); //Error: An rValue reference cannot be pointed to a lValue. foo(5); //5 is an rvalue (temporary) foo(b + 3); //b+3 is also an rvalue // int&& c = b; //Error. An rValue reference cannot be pointed to a lValue. int&& d = 5; //Compiles with no error. cout << "Value in d: " << d << endl; return 0; }
Output
Value received: 5 Value received: 13 Value in d: 5
In C++, a single ampersand (&) declares a reference, which is used to get the memory address of a variable. Double Ampersand (&&) is used to declare an rvalue reference as discussed above, which allows you to bind to temporary (rvalue) variables.
Here we will read more about these two in detail.
C++ Single Ampersand (&)
There are three main uses of the single ampersand in C++;
Accessing Memory Address
The most common use of the & operator is to get the memory address of a variable; therefore, here it does not give the value of a variable, but provides its location in memory. This is done using a pointer.
Syntax
Here is the following syntax for this.
pointer_type *pointer_name = &variable_name;
Example
#include <iostream> using namespace std; int main() { int x = 10; int *ptr = &x; // Pointer 'ptr' stores the memory address of 'x' cout << "Memory address of x: " << &x << endl; // Directly using &x to get memory address cout << "Pointer ptr holds the address: " << ptr << endl; // ptr stores the memory address cout << "Value at the address stored in ptr: " << *ptr << endl; // Dereferencing ptr to get value of 'x' return 0; }
Output
Memory address of x: 0x7ffce192faf4 Pointer ptr holds the address: 0x7ffce192faf4 Value at the address stored in ptr: 10
Explanation
In the above example, the pointer is used to store and access the memory address of a variable using the & (address-of) and * (dereference) operators.
Here, a pointer ptr of type int* is declared and stores the memory address of the variable x using the & operator. The & operator doesn't give the value of x but provides the memory location of x.
Then dereferencing *ptr is used to access the value stored at the memory address.
Creating a Variable Reference
It is used to create a reference to a variable, where this reference is just like another name for an existing variable.
Syntax
type &reference_name = existing_variable;
Here, type is the data type of the variable (e.g., int, double, char, etc.).
& is reference operator.
Example
#include <iostream> using namespace std; int main() { int a = 10; int &ref = a; cout << "Original value of a: " << a << endl; cout << "Reference value: " << ref << endl; ref = 20; // Changing the value of 'ref', which also changes 'a' cout << "New value of a: " << a << endl; cout << "New value of ref: " << ref << endl; return 0; }
Output
Original value of a: 10 Reference value: 10 New value of a: 20 New value of ref: 20
Explanation
In the above code, a reference to a is declared using &, which means now ref and a both refer to the same memory location.
Therefore, whatever changes we make to the value of ref, it will also change the value of a, as they both point to the same location.
Modifying an Argument by Reference
It is also used to pass arguments by reference, which allows the function to modify the original value. Here, the function directly works with the memory location of the argument, not a copy.
Syntax
void function_name(type ¶meter) { // Function body }
Example
#include <iostream> using namespace std; void increaseByTen(int &num) { num = num + 10; // Directly modifies the original value of num } int main() { int number = 5; cout << "Before: " << number << endl; increaseByTen(number); // Pass number by reference cout << "After: " << number << endl; return 0; }
Output
Before: 5 After: 15
Explanation
The above code shows the use of references to modify the original variable, which is passed into a function.
Here, the function takes an integer reference (int &num) as its parameter, and as num is a reference to the original variable, any modification to num will directly affect the original variable passed to it.
C++ Double Address Operator (&&)
The double address operator (&&) in C++ is used to declare an rvalue reference, which is used to bind to temporary objects.
What is rvalue?
For this, let's first understand the difference between rvalue and lvalue.
The lvalue (Left side of assignment) is the object which has a name and a memory address and can appear on the left or right of = and can bind to T&.
Example: int x = 10; Here, x is an lvalue.
The rvalue(Right side of assignment) is a temporary object/value, which does not have a name and cannot appear on the left-hand side of an assignment. This exists only during the expression and can bind to T&&.
Example: 10, x + y, 5 * 2 are rvalues.
Syntax
Here is the following syntax for it.
datatype&& reference_name = temporary_value;
Example
#include <iostream> using namespace std; int getValue() { return 42; // Returns a temporary (rvalue) } int main() { int&& ref = getValue(); // rvalue reference to a temporary value cout << "Value using rvalue reference: " << ref << endl; // Modifying the value ref = 100; cout << "Modified value: " << ref << endl; return 0; }
Output
Value using rvalue reference: 42 Modified value: 100
Explanation
In the above code, a function getValue() returns the integer value 42, which is an rvalue, meaning a value without any name, also known as a temporary object.
This temporary value can be treated like a regular value, but it's mostly discarded after use.
So, ref is an rvalue reference, which points to 42 and prints 42, but when assigning 100 to ref, even though ref was originally bound to a temporary value, it behaves just like a regular variable, and its value can be modified.
Therefore, in conclusion, C++ references (&) can only bind to lvalues (named variables), but temporary values like 42 are rvalues, and cannot be bound to normal references. So, C++11 introduced && to allow binding to rvalues.