In C++, a namespace is a collection of related names or identifiers (functions, class, variables) which helps to separate these identifiers from similar identifiers in other namespaces or the global namespace.
The identifiers of the C++ standard library are defined in a namespace called std
.
In order to use any identifier belonging to the standard library, we need to specify that it belongs to the std
namespace. One way to do this is by using the scope resolution operator ::
. For example,
std::cout << "Hello World!";
Here, we have used the code std::
before cout
. This tells the C++ compiler that the cout
object we are using belongs to the std
namespace.
C++ std Identifiers
All the standard library identifiers provided by the standard header files like <iostream>
, <string>
, <vector>
, etc. are declared in the std
namespace.
For example, identifiers cin
and cout
are defined inside the standard header file <iostream>
of the namespace std
.
Utilizing std Identifiers
We can utilize identifiers of the std
namespace in our program with:
- the
::
operator - the
using
declaration - the
using
directive
std Namespace Using :: Operator
The first way we access identifiers in the std
namespace is by directly qualifying the identifier with the prefix std::
. Here,
std
is the C++ standard library namespace::
is the scope resolution operator
For example,
#include <iostream>
int main() {
std::string first_name;
std::cout << "Enter your first name: ";
std::cin >> first_name;
std::cout << "Hello " << first_name << "!" << std::endl;
std::cout << "Welcome!";
return 0;
}
Output
Enter your first name: Marty Hello Marty! Welcome!
In the above example, we are using identifiers from the std
namespace directly using the scope resolution operator ::
.
Notice that we have prefixed std::
before string
, cin
, cout
, and endl
by writing:
std::string
std::cin
std::cout
std::endl
If we remove the std::
prefix from the codes above, we will get an error.
std Namespace With using Declaration
We can bring selected identifiers to the current scope with the help of the using declaration. To do this, we utilize the using
keyword.
By doing this, we won't need to prefix the specified identifiers with std::
. For example,
#include <iostream>
// using declartion for cout, endl and string
using std::cout;
using std::endl;
using std::string;
int main() {
string first_name ;
cout << "Enter your first name: ";
std::cin >> first_name;
cout << "Hello " << first_name << "!" << endl;
cout << "Welcome!";
return 0;
}
Output
Enter your first name: Scarlet Hello Scarlet! Welcome!
In the above example, we have used the using
declaration for the identifiers we want to use from the std
namespace:
using std::cout;
using std::endl;
using std::string;
Here, we are telling the compiler that we want to bring only the identifiers cout
, endl
, and string
from the standard namespace to the current scope.
This allows us to prevent explicitly adding prefix std::
whenever we need to access any of those identifiers.
Notice that we have used std::cin
instead of cin
in our program:
std::cin >> first_name;
This is because we have not included std::cin
in our using declaration.
std Namespace With using Directive
We can use the using directive to bring all the identifiers of the namespace std
as if they were declared globally. To do this, we utilize the using
keyword.
By doing this, we can:
- avoid using the
std::
prefix - avoid utilizing the
using
declaration repeatedly
For example,
#include <iostream>
// using directive
using namespace std;
int main() {
string first_name ;
cout << "Enter your first name: ";
cin >> first_name;
cout << "Hello " << first_name << "!" << endl;
cout << "Welcome!";
return 0;
}
Output
Enter your first name: Jack Hello Jack! Welcome!
In the above example, we have used the using
directive to bring all the identifiers of the std
namespace to our program, including the string
, cout
, cin
, and endl
identifiers.
Notes:
- The using declaration only brings the specified identifiers of the namespace into the current scope.
- The using directive brings all the identifiers of a namespace into the current scope.
Bad Practice: using namespace std
Since using namespace std
brings all the identifiers from the std
namespace into the global namespace, this can create naming conflicts with other namespaces. For instance, there may be other entities with the name cout
other than the one in the std
namespace.
So if we are using that other namespace (with the other cout
entity) along with the std
namespace, then the compiler will not know which cout
to use. As a result, we'll get an error whenever we use cout
.
Let us look at an example,
#include <iostream>
using namespace std;
// function template for swapping numbers
template <class T>
void swap (T& a, T& b) {
cout << "Before Swapping\na = " << a << " and b = " << b << endl;
T temp = a;
a = b;
b = temp;
cout << "After swapping\n";
cout << "a = " << a << " and " << b << " = " << b << endl;
}
int main() {
int a = 1;
int b = 2;
swap(a, b);
return 0;
}
Output
error: call of overloaded 'swap(int&, int&)' is ambiguous
In the above example, we have created our own version of the swap()
function using a function template. We then tried calling the swap()
function with integers a = 1
and b = 2
,
swap(a, b);
The swap()
function takes two integers and swaps them as well as displays the value of a and b before and after swapping. But we get an error if we try to run the code.
Why Do We Get an Error?
Here, we are getting an error because of the following code in our program:
using namespace std;
This is a using-directive which brings all the identifiers from the standard namespace to the current namespace. But the std
namespace includes its own swap()
function.
So, the compiler is unable to determine which version of swap()
to use: std::swap()
or the custom function we have created.
In order to avoid this error, we must remove the using namespace std;
code from our program.
Potential Professional Problems
Suppose you are working on a large program or project. Let's say you are using a library called swapLib which implements its own swap()
function.
If you utilize using namespace std
, it may create ambiguity just like in our example i.e. whether to use swap()
from the swapLib library or the standard namespace.
Note: If you are using only a few names from the standard library, it is better to use using-declaration to selectively bring identifiers.