Namespaces

Namespaces were introduced to the C++ Standard in 1995 and usually they are defined like this:

A namespace defines a new scope. They provide a way to avoid name collisions.

Consider a situation where you are you are the teacher of a classroom of students. For sake of example, let’s say there are two boys named “Joy”. If you were to say, “Joy got an A on his test”, which Joy are you referring to? Nobody knows, unless you have a way to disambiguate which Joy you mean. Perhaps you point at one, or use their last names. If the two Joy’s were in different classrooms, there wouldn’t be a problem — the problem is really that there are two things with the same name in the same place. And in fact, as the number of students in the classroom increase, the odds of having two students with the same first name increases exponentially.

A similar issue can arise in programming when two identifiers (variable and/or function names) with the same name are introduced into the same scope. When this happens, a naming collision will result, and the compiler will produce an error because it does not have enough information to resolve the ambiguity. As programs get larger and larger, the number of identifiers increases linearly, which in turn causes the probability of naming collisions to increase exponentially.

Let’s take a look at an example of a naming collision. In the following example, foo.h and goo.h are the header files that contain functions that do different things but have the same name and parameters.

foo.h:

goo.h:

main.cpp:

If foo.h and goo.h are compiled separately, they will each compile without incident. However, by including them in the same program, we have now introduced two different functions with the same name and parameters into the program, which causes a naming collision. As a result, the compiler will issue an error:

c:\VCProjects\goo.h(4) : error C2084: function 'int __cdecl DoSomething(int,int)' already has a body

In order to help address this type of problem, the concept of namespaces was introduced.

What is a namespace?

A namespace defines an area of code in which all identifiers are guaranteed to be unique. By default, all variables and functions are defined in the global namespace.

Reasons for using namespace

1- Avoid name collisions.

As speicified before it’s the common reason, in this case their use are just useful for the compiler, no added value for the developer to make the code more readable and maintanable.

2- Modularize the application

Modern C++ librarires use extensively the namespaces to modalirize their code base, and they use the  “Namespace-by-feature” approach. Namespace-by-feature uses namespaces to reflect the feature set. It places all items related to a single feature (and only that feature) into a single namespace. This results in namespaces with high cohesion and high modularity, and with minimal coupling between namespaces. Items that work closely together are placed next to each other.

3- Anonymous namespace.

Namespace with no name avoids making global static variable. The “anonymous” namespace you have created will only be accessible within the file you created it in.

4- work arround of the enum issue.

“Traditional” enums in C++ export their enumerators in the surrounding scope ,which can lead to name collisions, if two different enums in the same have scope define enumerators with the same name,

In a large project, you would not be guaranteed that two distinct enums don’t both called with the same name. This issue was resolved in C++11, using  enum class which will implicitly scope the enum values within the enum’s name.

Many years ago the trick of declaring an enum inside a namespace is used, for example instead of declaring an enum like this

enum status{
  status_ok, status_error
};

it’s declared inside an namespace:

namespace status{
enum status{
        ok, error
 };
}

Many C++ projects use this trick, for example the Unreal Engine source code use widely this technique.

5- Hiding details by convention

For templated libraries where the code is implemented in header files, it’s interesting to find a way to inform the library user that he dont need to use directly some specific types because they concern only the implementation. In C# the “internal” keyword did the job, but in C++ there’s no way to hide public types to the library user.

A common idiom in modern C++, pioneered by the developers of the Boost libraries, is to separate symbols that form part of the implementation of your module (that is, don’t form part of the public API) but that have to be publicly available into a separate sub-namespace, by convention named detail.

Definition

A namespace (sometimes also called a name scope) is an abstract container or environment created to hold a logical grouping of unique identifiers or symbols (i.e., names). An identifier defined in a namespace is associated only with that namespace. The same identifier can be independently defined in multiple namespaces. That is, the meaning associated with an identifier defined in one namespace may or may not have the same meaning as the same identifier defined in another namespace. Languages that support namespaces specify the rules that determine to which namespace an identifier (not its definition) belongs.

The functionality of namespaces is especially useful in the case that there is a possibility that a global object or function uses the same identifier as another one,causing redefinition errors.

Creating a Namespace

  • Creation if Namespace is similar to that the creation of Class.
  • Namespace declaration occur only at a global scope.
  • Namespace declaration can be nested within another namespace.
  • Namespace declarations don’t have access specifiers(public or private).
  • No need to give Semicolon at the closing brace of defination of namespace.
  • We can split definition of namespace over several units.

Syntax

namespace namespace_name
{
//member declarations
}

Live Example :

//In firstHeader.h
namespace ns1
{
   class one
   {
      //----Declarations---
   };
   class two
   {
      //----Declarations---
   };
}

//In secondHeader.h
namespace ns1    // can continue the defination of ns1 over multiple header files
{
   class three
   {
      //----Declarations---
   };
}

UNNAMED Namespaces

  • Unnamed namespaces are the replacement for static declaration of variables.
  • They are directly usable in the same program and are used for declaring unique identifiers.
  • In unnamed namespace,name of the namespace is not mentioned in the declaration of the namespace.
  • The name of the namespace is uniquely generated by the compiler.
  • The unnamed namespace you have created are accessible in the file you have created it.
#include<iostream>
using namespace std;

namespace
{
    int i;
}

int main()
{
    i=10;
    cout<< "Value : "<<i;
    return 0;
}
Output:
Value : 10

 

How to Use Namespaces in C++ Programming Language :

Following are the ways to refer to namespace members:

Way 1 : Using Scope Resolution :

In this method, we use the namespace name, scope resolution operator (::) and member of that namespace.

Way 2 : Using Directive:

We can use ‘using’ directive to specify the namespace.

#include<iostream>
using namespace std;

namespace first
{
int i;
}

namespace second
{
int i;
}

int main()
{
first::i=1;   //scope resolution
second::i=2;

using first::i; //using directive
cout<<i;
}

You can also avoid prepending of namespaces with the using namespace directive. This directive tells the compiler that the subsequent code is making use of names in the specified namespace. The namespace is thus implied for the following code:

#include <iostream>
using namespace std;

// first name space
namespace first_space{
   void func(){
      cout << "Inside first_space" << endl;
   }
}
// second name space
namespace second_space{
   void func(){
      cout << "Inside second_space" << endl;
   }
}
using namespace first_space;
int main ()
{
   // This calls function from first name space.
   func();  
   return 0;
}

If we compile and run above code, this would produce the following result:

Inside first_space

The using directive can also be used to refer to a particular item within a namespace. For example, if the only part of the std namespace that you intend to use is cout, you can refer to it as follows:

using std::cout;

Subsequent code can refer to cout without prepending the namespace, but other items in the stdnamespace will still need to be explicit as follows:

#include <iostream>
using std::cout;

int main ()
{
   cout << "std::endl is used with std!" << std::endl;  
   return 0;
}

If we compile and run above code, this would produce the following result:

std::endl is used with std!

Names introduced in a using directive obey normal scope rules. The name is visible from the point of theusing directive to the end of the scope in which the directive is found. Entities with the same name defined in an outer scope are hidden.

 

Way 3 : Using declaration:

It is a declaration within the current scope. This means it can override names from a using directive.

#include<iostream>
using namespace std;

namespace first
{
int i;
}
using namespace first;// using declaration
int main()
{
i=2;
cout<<"Value : "<<i<<endl;
}

Output:

Value : 2

 

Different Varieties of Using Namespace :

1.We can Have Class Definition inside Namespace

#include <iostream>
using namespace std; 

namespace MyNameSpace { 
  int num1; 
  int num2; 

  class Student
  { 
     int marks; 
   public: 
     Student() {  
        marks = num1; 
     } 
  }; 
} 

int main() 
{ 
  MyNameSpace::num1 = 70; 
  MyNameSpace::num2 = 90; 
  MyNameSpace::Student ob1(); 
}
  • num1, num2 are two variables under same namespace name “MyNamespace”.
  • We can Initialize them in main function by using Scope Resolution Operator.
  • We can Declare Class inside Namespace and thus we can have multiple classes with same name but they must be in different namespace.

2.We can Have Same Class Definition inside different Namespace

#include <iostream> 
using namespace std; 
 
namespace MyNameSpace1 { 
  int num1; 
  int num2; 
 
  class Student
  { 
     int marks; 
   public: 
     Student() {  
        marks = num1; 
     } 
  }; 
} 

namespace MyNameSpace2 { 
  int num1; 
  int num2; 
 
  class Student
  { 
     int marks; 
   public: 
     Student() {  
        marks = num1; 
     } 
  }; 
} 
 
int main() 
{ 
  MyNameSpace1::num1 = 80; 
  MyNameSpace1::num2 = 50; 
  MyNameSpace1::Student ob1(); 
}

Let us see how namespace scope the entities including variable and functions:

#include <iostream>
using namespace std;

// first name space
namespace first_space{
   void func(){
      cout << "Inside first_space" << endl;
   }
}
// second name space
namespace second_space{
   void func(){
      cout << "Inside second_space" << endl;
   }
}
int main ()
{
   // Calls function from first name space.
   first_space::func();
   
   // Calls function from second name space.
   second_space::func(); 

   return 0;
}

If we compile and run above code, this would produce the following result:

Inside first_space
Inside second_space

alias definition

We have the possibility to define alternative names for namespaces that already exist. The form to do it is:

namespace new_name = current_name ;

Namespace std

One of the best examples that we can find about namespaces is the standard C++ library itself. As defined in the ANSI C++ standard, all the classes, objects and functions of the standard C++ library are defined within namespace std.

Almost all compilers, even those complying with ANSI standard, allow the use of the traditional header files (like iostream.h, stdlib.h, etc), the ones we have used througout this tutorial. Nevertheless, the ANSI standard has completely redesigned these libraries taking advantage of the templates feature and following the rule to declare all the functions and variables under the namespace std.

The standard has specified new names for these “header” files, basically using the same name for C++ specific files, but without the ending .h. For example, iostream.h becomes iostream.

If we use the ANSI-C++ compliant include files we have to bear in mind that all the functions, classes and objects will be declared under the std namespace. For example:

// ANSI-C++ compliant hello world
#include <iostream>

int main () {
  std::cout << "Hello world in ANSI-C++\n";
  return 0;
}
Hello world in ANSI-C++

Although it is more usual to use using namespace and save us to have to use the scope operator :: before all the references to standard objects:

// ANSI-C++ compliant hello world (II)
#include <iostream>
using namespace std;

int main () {
  cout << "Hello world in ANSI-C++\n";
  return 0;
}
Hello world in ANSI-C++