C++ Namespaces and Using Declarations

Learn how we can use namespaces to keep related variables, functions and classes together.
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

3D art showing a fantasy character
Ryan McCombe
Ryan McCombe
Posted

When working with bigger projects, a problem can arise when many different identifiers exist in the same project. For example, two variables, functions or classes that have the same name.

The way this problem is solved is by the introduction of namespaces.

Creating a Namespace

We can wrap sections of our code inside a namespace as shown below.

namespace Math {
  // your code here
}

We can popualte namespaces with any of the constructs we've seen before. This can include variables, functions and even complete classes:

namespace Math {
  int Add(int x, int y) {
    return x + y;
  }

  float Pi { 3.14 };

  float Circumference (float Diameter) {
    // Because this function is in the same namespace as
    // the pi variable, we can access Pi as normal here
    return Diameter * Pi;
  }

  class Square {
    float SideLength { 5.0 };
    float Area() { return SideLength * SideLength };
  }
}

Test your Knowledge

How can we create a namespace called Utilities?

Accessing Things inside C++ Namespaces

In the earlier example, we saw that members of a namespace can access other members of their namespace as normal:

namespace Math {
  float Pi { 3.14 };
  float Circumference(float Diameter) {
    // We can access Pi here as we're in the same namespace
    return Diameter * Pi;
  }
}

To access namespace members from outside the namespace, we need the Scope Resolution Operator, ::

For example, the following statement accesses the Add function and the Pi variable, which are both inside the Math namespace:

Math::Add(10, Math::Pi);

Test your Knowledge

How can we call the Square function within the Utilities namespace?

namespace Utilities {
  void Square() {};
};

C++ Nested Namespaces

Namespaces can be nested inside other namespaces in C++

namespace Math {
  int Add(int x, int y) {
    return x + y;
  }
  namespace Geometry {
    float Pi { 3.14f };
  }
}

To access these nested identifiers, we can can use the :: operator multiple times:

Math::Add(10, Math::Geometry::Pi)

C++ using Declarations

Starting from the very first lesson, we've had a line of code in our files that we've left unexplained thus far:

using namespace std;

Predictably, this line is related to namespaces.

The effect of this using declaration was an instruction that asks the compiler: "if an identifier in this scope is not found, try searching for it in the std namespace".

This using statement has been necessary every time we used cout and endl. These identifiers were actually in the std namespace.

Without the using declaration, we would needed to use the scope resolution operator. Instead of this:

using namespace std;
cout << "Hello world!" << endl;

We'd have needed to do this:

std::cout << "Hello world!" << std::endl;

We can use using declarations with any namespace - not just std:

namespace Maths {
  float Pi { 3.14f };
}

using namespace Maths;
using namespace std;

cout << Pi << endl;

Test your Knowledge

What statement can we add on line 5 below that will make line 7 work?

1namespace Utilities {
2  void Square() {};
3};
4
5// ?
6
7Square();
8

Should I use using namespace Statements?

Probably not. Namespaces exist to help us organise code - a using namespace declaration effectively subverts that organisation.

We will continue to use them in our lessons. This is only for two reasons:

  • We want to keep our lines as short as possible - horizontal space is limited when we're presenting code on a mobile-friendly website
  • Naming collisions are less of a problem when dealing with simple, tutorial examples.

But, in real projects, we should be cautious about adopting using declarations.

Remember too how #include directives work - if we have a using declaration that is scoped to an entire file, that would also effect any file that includes it.

This can cause things to get out of hand quite quickly so, if using declarations are going to be adopted, be particularly cautious when using them on files that are likely to be included in other files.

The Unreal coding standard asks for using declarations to never be used in the global scope:

Do not put using declarations in the global scope, even in a .cpp file. It's okay to put using declarations within another namespace, or within a function body.

And the Google C++ standard asks that using declarations never be used, anywhere:

Do not use using-directives (e.g., using namespace foo).

If we want to use using statements, there are two ways we can get their benefits, whilst minimising their drawbacks. The first is to use them only in the scope they're necessary. The second is to restrict them to only using the specific identifiers we need.

Scoped using Declarations

Using declarations follow the normal block scoping rules. A using declaration outside of any block has "global" scope, and will apply to the entire file.

This can be problematic, especially if that file goes on to be added to a load of other files, via the #include directive.

As an alternative to global using declarations, we can place them inside blocks - usually function bodies or other namespaces. This wil limit their effect to just the scope of that block.

void Hello() {
  using namespace std;
  cout << "Hello ";
}

void World() {
  // Error!  The using declaration only applies to the block where it is used
  cout << "World"
}

int main() {
  Hello();
  World();
}

Restrict using Declarations to Specific Identifiers

Rather than having a using statement that covers the entire std namespace, we can restrict it just to specific identifiers.

For example, to use it with just std::cout and std::endl, we could write this:

#include <iostream>

using std::cout, std::endl;

int main() {
  cout << "Hello world!" << endl;
}

Was this lesson useful?

Ryan McCombe
Ryan McCombe
Posted
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Namespaces, Enums and Structs
3D art showing a progammer setting up a development environment
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, unlimited access!

This course includes:

  • 66 Lessons
  • Over 200 Quiz Questions
  • Capstone Project
  • Regularly Updated
  • Help and FAQ
Next Lesson

C++ Namespaces vs Classes

Learn how we can use namespaces in the design of our software, and why we'd want to use an anonymous namespace.
3D art showing a fantasy character
Contact|Privacy Policy|Terms of Use
Copyright © 2023 - All Rights Reserved