Search

4.3b — Namespaces

In lesson 1.8a -- Naming conflicts and the std namespace, we introduced the concept of naming conflicts and namespaces. This lesson builds upon those topics.

A naming conflict occurs when two identifiers are introduced into the same scope, and the compiler can’t disambiguate which one to use. When this happens, compiler or linker 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 same scope (the global scope), 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, global variables and normal functions are defined in the global namespace. For example, take a look at the following snippet:

Both global variable g_x and function foo() are defined in the global namespace.

In the example program above that had the naming collision, when main() #included both foo.h and goo.h, both versions of doSomething() were included into the global namespace, which is why the naming collision resulted.

In order to help avoid issues where two independent pieces of code have naming collisions with each other when used together, C++ allows us to declare our own namespaces via the namespace keyword. Anything declared inside a user-defined namespace belongs to that namespace, not the global namespace.

Here is an example of the headers in the first example rewritten using namespaces:

foo.h:

goo.h:

Now the doSomething() inside of foo.h is inside the Foo namespace, and the doSomething() inside of goo.h is inside the Goo namespace. Let’s see what happens when we recompile main.cpp:

The answer is that we now get another error!

C:\VCProjects\Test.cpp(15) : error C2065: 'doSomething' : undeclared identifier

What happened is that when we tried to call the doSomething() function, the compiler looked in the global namespace to see if it could find a definition of doSomething(). However, because neither of our doSomething() functions live in the global namespace any more, it failed to find a definition at all!

There are two different ways to tell the compiler which version of doSomething to use, via the scope resolution operator, or via using statements (which we’ll discuss in the next lesson).

Accessing a namespace with the scope resolution operator (::)

The first way to tell the compiler to look in a particular namespace for an identifier is to use the scope resolution operator (::). This operator allows you to prefix an identifier name with the namespace you wish to use.

Here is an example of using the scope resolution operator to tell the compiler that we explicitly want to use the version of doSomething that lives in the Foo namespace:

This produces the result:

7

If we wanted to use the version of doSomething() that lives in Goo instead:

This produces the result:

1

The scope resolution operator is very nice because it allows us to specifically pick which namespace we want to look in. It even allows us to do the following:

This produces the result:

7
1

It is also possible to use the scope resolution operator without any namespace (eg. ::doSomething). In that case, it refers to the global namespace.

Multiple namespace blocks with the same name allowed

It’s legal to declare namespace blocks in multiple locations (either across multiple files, or multiple places within the same file). All declarations within the namespace block are considered part of the namespace.

add.h:

subtract.h:

main.cpp:

This works exactly as you would expect.

The standard library makes extensive use of this feature, as all of the different header files included with the standard library have their functionality inside namespace std.

Nested namespaces and namespace aliases

Namespaces can be nested inside other namespaces. For example:

Note that because namespace Goo is inside of namespace Foo, we access g_x as Foo::Goo::g_x.

In C++17, nested namespaces can also be declared this way:

Because typing the fully qualified name of a variable or function inside a nested namespace can be painful, C++ allows you to create namespace aliases.

It’s worth noting that namespaces in C++ were not designed as a way to implement an information hierarchy -- they were designed primarily as a mechanism for preventing naming collisions. As evidence of this, note that the entirety of the standard template library lives under the singular namespace std::. Some newer languages (such as C#) differ from C++ in this regard.

In general, you should avoid nesting namespaces if possible, and there are few good reasons to nest them more than 2 levels deep. However, in later lessons, we will see other related cases where the scope resolution operator needs to be used more than once.

4.3c -- Using statements
Index
4.3a -- Scope, duration, and linkage summary

172 comments to 4.3b — Namespaces

  • You wouldn't usually have two namespaces in one file.

    adding.hpp

    adding.cpp

    • Dear Mr Nas!
      Thank you for  taking your golden time to me.
      What bout header file? This is what i have been confusing  of. That means can we have to  add a .hpp file for the header with header guards like..
      #ifndef ADDING_h
      #define ADDING_H
      double add(double my_expense,double my_income);
      double add(double my_salary,double  my_bonus); //it can be a function with another identifier.
      #endif
      or the name space uses as a header guard like above?
      This my last question sir!!!
      Really sorry for the ping pong and thank you for your Patience indeed!!!!!

  • Dear Blessed teacher Mr. Alex!
    I would like to sorry in advance if my question was initially pointed out by other person.
    My question is focused on synchronization b/n namespaces,headers header's definition
    1) Is a  .h file the only place for namespace declaration? Can we declare and define namespaces in a .cpp file?

    2) for example iostream is a header for d/t forward declarations that their definition is found in run time library. what about the namespaces? are they declared in another .h file? or in side iostream header file?

    3) during  namespace declaration we have to define the function or variable with in the block of a namespace that we need it to be unique.  Can we use this definition as a definition for header's file forward declaration (prototype)  or we have to define it in a   .CPP file for 2nd time too?  

       Stay blessed with you kindness Sir!!!!!

    • Hi!

      1,2) The namespace has to be in all files that declare/define members of the namespace

      3) I don't understand

      • Dear blessed Mr Nas!!!
        Thank you so much for a very swift  response as usual .Ok just help me to do the code for the below question. I will  get my answer from that.(I believe)

        let we say we have a header file called adding.h that have 2 prototypes....
        //Prototype1)  
        double add(double my_expense,double my_income);  
        //prototype 2)  
        double add(double my_salary,double  my_bonus);  // NOTE: let we think their definition  found in another adding.CPP file.
        And they have to be unique through namespaces.  prototype 1 in namespace my_usage{}
        and ptototype 2 in namespace myGain{}
        How can we do full code for the above ?

           With a huge respect and prayer for you  sir!!!!!!!!!

  • Hi there!

    Please use code tags when sharing code.

    1. Yes
    2. The namespace has to be around both, the declaration and the definition
    3. No, the function declarations have to be in the same namespace as their definitions.

  • I, like Jesper Nielson # April 12 2018 # struggled a little with the concept of not using namespaces more having spent many years using C# to develop forms and online calculators for specific formulae. Modern C# regularly encapsulates blocks of functions and classes into a Namespace such as the following:

    C++ seems more complicated using similar naming conventions but with different restrictions on their use, or with different concepts of meaning.

    • Hi Nigel!

      Other than @main, you can, and should, store everything in some kind of structure (struct, class, namespace, ...).
      Namespaces in cpp or usually used for entire projects, eg. when writing a library. Parts of that project are stored in classes.
      For the most part, the examples on learncpp are so small that they don't need any packaging.

  • Jesper Nielsen

    As a long time C# and before that Java programmer I find it hard to understand namespaces (and folders) are not used a lot more.
    But on the other hands Visual Studio really starts fighting you if you want to arrange your code...

  • Matt

    What would be considered a rule of thumb for "best practice" when it comes to namespaces, multiple files, etc?  To clarify my question (and to highlight why I am starting to get nervous at this point in the tutorial series): Every time I write a program from this point forward, should I be separating my individual functions into their own .cpp files, should I be giving all of my functions their own namespace, making ample use of .header files, using global const variables as often as possible, et cetera in the name of practicing the concepts?  Or, in contrast, should a 'minimalist' approach be used, using as few files as necessary for disambiguation, convenience, and clarity?

    Clearly, C++ has a ton of functionality and there are several ways to accomplish the same goal.  In the last chapter or so worth of lessons we have introduced a ton of tools/concepts that seem, if you'll excuse my saying so, almost unnecessary (considering what they offer can be accomplished without them using what we've learned prior).

    Perhaps I'm writing this because I'm feeling a bit overwhelmed and instead of learning simple exercises in syntax we're being familiarized with a myriad of options/tools - thanks for your time!

    • nascardriver

      Hi Matt!

      Further down the line you'll rarely have plain functions in their own file, because almost everything will be in a class. Each class will be in it's own file. If multiple classes have something in common (eg. they're all part of the same framework) they'll be in the same namespace (One namespace can stretch across multiple files). For the most part of the tutorials here a single-file approach fits best.

      > using global const variables as often as possible
      Global things are bad, avoid them.

    • Alex

      Nascardriver's answer is good.

      For these academic programs, a single file will typically suffice just fine.

      Multiple files become far more useful when:
      * You start writing lengthy, non-trivial programs and need the additional organization that multiple files can provide.
      * You start writing programs that make use of reusable code (that reusable code should live in separate .cpp/.h files). Classes (covered in chapter 8) really help with this.

      For the most part, you won't need to use your own namespaces. They're covered more so you understand how they work, not because we expect you to be creating your own. Same with global variables -- good to know they exist, but you should generally avoid them as much as possible. 🙂

  • nascardriver

    Hi Alex!

    I think the section "Nested namespaces and namespace aliases" could use a little C++17

  • Baljinder

    I just wanted to mention that under the 'Multiple namespace blocks with the same name allowed' section, the first sentence contains the following, "multiple places within in the same file". Perhaps, it would be clearer to say "multiple places in the same file" (i.e. without the word within).

Leave a Comment

Put all code inside code tags: [code]your code here[/code]