Learn C++ Namespace in a Easiest Way with Examples

A C++ namespace is a declarative region that gives the names of types, functions, variables, and other things within a scope.

C++ namespace
C++ namespace

What is a namespace in C++?

A namespace is an area for making declarations that gives the names of the types, functions, variables, and other things inside a resolution operator.

Namespaces are used to classify code logically and avoid name clashes, which are especially likely to happen when your code base contains several libraries.

All identifiers within the namespace outer scope operator can be seen by all other identifiers without any special conditions.

Identifiers outside of the namespace can be called and reach the members by using the fully qualified name for each identifier.

For Example:

namespace ExampleData
{
    class ObjectManager
    {
    public:
        void DoSomething() {}
    };
    void Func(ObjectManager) {}
}

Fill out the name completely:

ExampleData::ObjectManager mgr;
mgr.DoSomething();
ExampleData::Func(mgr);

To include one identifier in your scope, use a using declaration:

using ExampleData::ObjectManager;
ObjectManager mgr;
mgr.DoSomething();

Use a “using” directive to include everything in the namespace:

using namespace ExampleData;

ObjectManager mgr;
mgr.DoSomething();
Func(mgr);

Using directives

The using directive makes it possible to use all the names in a namespace without having to specify the namespace-name.

Use a using directive in an implementation file (i.e. *.cpp) if you use several different identifiers in a namespace.

If you only use one or two identifiers, consider a using-declaration only to bring those identifiers into the scope and not all the identifiers in the namespace.

Declaring namespaces and namespace members

Usually, a namespace is declared in a header file for organizing the elements.

If the code for a function is in a separate file, we should qualify the names of the functions.

For Example:

//exampleData.h
#pragma once
namespace ExampleDataServer
{
    void Foo();
    int Bar();
}

Even if we put a using directive at the top of the file, the fully qualified name should be used in the function implementations in exampledata.cpp:

#include "exampledata.h"
using namespace ExampleDataServer;

void ExampleDataServer::Foo() // use fully-qualified name here
{
   // no qualification needed for Bar()
   Bar();
}

int ExampleDataServer::Bar(){return 0;}

A namespace can be declared in more than one block in the same file or in more than one file.

During preprocessing, the compiler puts all the pieces together, and the resulting namespace has all the members that were declared in all the pieces.

This is shown by the fact that the std namespace is declared in each header file in the standard library.

// program sample created by Glenn
// defining_namespace_members.cpp
// C3039 expected
namespace V {
    void f();
}

void V::f() { }        // ok
void V::g() { }        // C3039, g() is not yet a member of V

namespace V {
    void g();
}

This error can happen when members of a namespace are declared in more than one header file, and those headers are not included in the right order.

What is a global namespace in C++?

The global scope, or global namespace logical scope, refers to the namespace scope at the very end of a program.

This is where objects, functions, types, and templates are defined.

A name has global variables when its declaration is outside of all blocks, namespaces, and classes.

What is namespace std in C++?

std,” which stands for “standard” is known to be a namespace whose members are used in the program.

So cout, cin, endl, etc. are all part of the “std” namespace. The iostream.h header file has this namespace.

Nested namespaces

Namespaces can be put inside each other.

A normal nested namespace has full access to the members of its parent, but the members of the parent don’t have full access to the nested namespace (unless it is declared as inline).

For Example:

namespace ExampleDataServer
{
    void Foo();

    namespace Details
    {
        int CountImpl;
        void Ban() { return Foo(); }
    }

    int Bar(){...};
    int Baz(int i) { return Details::CountImpl; }
}

Normal nested namespaces can be used to hide internal implementation details that aren’t part of the parent namespace’s public interface.

C++ Inline namespace

In an inline namespace, members are treated the same as members of the parent namespace, which is different from a normal nested namespace.

It also lets us declare a specialization for a template that is declared in the inline namespace in a parent namespace.

For Example:

//Header.h
#include <string>

namespace Test
{
    namespace old_ns
    {
        std::string Func() { return std::string("Hi from old"); }
    }

    inline namespace new_ns
    {
        std::string Func() { return std::string("Hi from new"); }
    }
}

#include "header.h"
#include <string>
#include <iostream>

int main()
{
    using namespace Test;
    using namespace std;

    string s = Func();
    std::cout << s << std::endl; // "Hi from new"
    return 0;
}

The example below shows how to declare a specialization in a parent of a template that is declared in an inline namespace:

namespace Parent
{
    inline namespace new_ns
    {
         template <typename T>
         struct C
         {
             T member;
         };
    }
     template<>
     class C<int> {};
}

The inline the keyword has to be used on the first namespace declaration in a compilation unit.

For Example:

namespace Example
{
    namespace v_10
    {
        template <typename T>
        class Funcs
        {
        public:
            Funcs(void);
            T Add(T a, T b);
            T Subtract(T a, T b);
            T Multiply(T a, T b);
            T Divide(T a, T b);
        };
    }

    inline namespace v_20
    {
        template <typename T>
        class Funcs
        {
        public:
            Funcs(void);
            T Add(T a, T b);
            T Subtract(T a, T b);
            T Multiply(T a, T b);
            std::vector<double> Log(double);
            T Accumulate(std::vector<T> nums);
      };
    }
}

C++ Namespace alias

Names for namespaces have to be unique which usually means they can’t be too short.

If a name is too long to read in code or is hard to type in a header file where using directives can’t be used, we can make a namespace alias that stands in for the real name and group named entities.

For Example:

namespace a_very_long_namespace_name { class Foo {}; }
namespace AGLNN = a_very_long_namespace_name;
void Bar(AGLNN::Foo foo){ }

C++ anonymous namespace

We can make a namespace that is explicit but not give it a name:

namespace
{
    int MyFunc(){}
}

Unnamed or anonymous namespaces are handy when we want to hide variable declarations from other files (i.e., give them internal linkage) without defining a named namespace.

Summary

This article discusses the C++ namespace. It also tackles directives, namespace members, global namespace, namespace std, nested namespaces, inline namespace, namespace alias, and anonymous namespace.

I hope this lesson has helped you learn a lot.

Check out my previous and latest articles for more life-changing tutorials which could help you a lot.

Leave a Comment