Namespaces

Declaring and Defining Namespaces

The simplest way to create a namespace is to simply write down the keyword namespace, give it a name, and then open a pair of curly braces. Everything declared between the opening and closing braces will be in that namespace.

This completely compilable program declares a namespace called Math and contains one function inside of it:

#include <iostream>

namespace Math
{
    int square(int x)
    {
        return x * x;
    }
}

int main()
{
    int result{ Math::square(7) };
    std::cout << "Square is " << result << '\n';
    return 0;
}

The namespace Math begins the declaration. The curly brace opens and closes the body of the namespace where the int square function is declared. The square function is within the Math namespace. That means its full name when referenced is Math::square; an attempt to call just square(7) will give you a compiler error because no square function will be found in the global namespace.

There may be any amount of definitions declared within a namespace. This program puts both a variable and a function in the Utility namespace.

#include <iostream>

namespace Utility
{
    int counter{ 0 };

    void increment()
    {
        ++counter;
    }
}

int main()
{
    Utility::increment();
    Utility::increment();
    std::cout << "Counter is " << Utility::counter << '\n';
    return 0;
}

The namespace Utility holds an int variable called counter which is initialized to 0. It also contains a void increment function which takes the value that counter is, increases it by 1, and stores it back in counter. Because they are within the same namespace, all references made to these definitions outside of the namespace must be made with Utility::. After two calls to Utility::increment, the value in Utility::counter is 2.

You can reopen any namespace to add more to it. The following example has two blocks that start with namespace Logging. The compiler knows this and adds definitions declared in subsequent blocks of the same namespace.

#include <iostream>

namespace Logging
{
    void info(const char* message)
    {
        std::cout << "[INFO] " << message << '\n';
    }
}

namespace Logging
{
    void error(const char* message)
    {
        std::cout << "[ERROR] " << message << '\n';
    }
}

int main()
{
    Logging::info("Program started.");
    Logging::error("Something went wrong.");
    return 0;
}

The first namespace Logging declares a function info. The second namespace Logging block that follows declares another function, error. When they are compiled, those two functions appear in the same namespace called Logging, and can be reached with the same scope-resolution operator (::). The compiler only allows this if you are only adding more declarations to the same namespace; otherwise, if they are separate namespaces, they are completely unrelated, even if their name may be the same!

Declarations outside of any namespace by default belong to the global namespace. It's good to keep things separated, but easy to mistakenly mix them up. The following example contrasts global and namespaced functions.

#include <iostream>

namespace Display
{
    void show()
    {
        std::cout << "Inside Display" << '\n';
    }
}

void show()
{
    std::cout << "Inside global" << '\n';
}

int main()
{
    Display::show();
    show();
    return 0;
}

Here we have two functions called show: one in the Display namespace and one in the global namespace. By writing Display::show we specify that we want to call the function in the Display namespace, while simply writing show tells us to go to the global scope. The output will reflect their distinct definitions.

You essentially create a new, separate scope when you declare a namespace. Everything you add in that namespace cannot be seen by anything in any other namespace, or in the global namespace, unless you specifically tell it where to look using the scope-resolution operator (::).

0 comments

No comments yet. Be the first.

Add a comment

About CppLearn

CppLearn is an interactive, free reference for modern C++. In each lesson, you'll find out how the language works, rather than just lines of code that you can copy and paste. We cover concepts starting from beginner lessons on fundamentals and proceed to templates, move semantics, smart pointers, and areas that usually trap or scare C++ learners.