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
usingdeclaration - the
usingdirective
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,
stdis 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::stringstd::cinstd::coutstd::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
usingdeclaration 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.