Namespace

Namespace purpose is to to resolve naming conflict, where two functions from different header file included accidentally have the same name, by explicitly specify their namespace, Namespace1::Function and Namespace2::Function. In general, use namespaces only when the code is expected to be used in external software sites.

All C++ standard library use this feature, but include them as #include <iostream> rather then #include <iostream.h> because the later will ignore namespace checking for C backward compatibility. Their namespace is std.

There are three ways of invoking a particular function:

The outermost namespace scope of a program is called global scope or global namespace scope. Programmer can define user-declared namespaces nested within the global scope using namespace definitions. Each user-declared namespace is a different scope, and each is distinct from the global scope. As with the global scope, user-declared namespaces can contain declarations and definitions for objects, functions, types and templates as well as other nested user-declared namespaces.


Member of global namespace will be hidden by names declared in nested local scopes if same. To refer to the hidden name, add scope operator in front.
::Function(arguments);

Name resolution hierarchy - Local scope first, class scope second, namespace scope third, global scope last.
int height_;

namespace Graphic {

int height_;

class Screen {
public:
  Screen(long height_)
  {
    height_ = 0; // refer to local parameter
    this->height_ = 2; // refer to class data member
    Graphic::height_ = 4; // refer to namespace object
    ::height_ = 0; // refer to global object
  }
private:
  short height_;
};

}

A small trick to remember by looking up the name that appears in a member definition located outside its class definition. The names by which the member name is qualified indicate the reverse order in which the scopes are searched. For example Graphic::Screen::Screen(long);.


Using directive makes the namespace member names visible as if they were declared outside the namespace at the location where the namespace definition is located. Unlike using declaration, it does not declare local aliases for the namespace member names. Rather, it has the effect of lifting the namespace members into the scope containing the namespace definition. The effects are
namespace blip {
  int bi = 16, bj = 15, bk = 23;
}
int bj = 0;
void manip()
{
  using namespace blip; // using directive -
                        // clash between ::bj and blip::bj
                        // detected only when bj is used
  int bk = 97;          // local bk hides blip::bk
  ++bi;                 // sets blip::bi to 17
  ++bj;                 // error: ambiguous
                        // global bj or blip::bj?
  ++::bj;               // ok: sets global bj to 1
  ++blip::bj;           // ok: sets blip::bj to 16
  ++bk;                 // sets local bk to 98
}
  1. Using directives are scoped. Since it is in manip() it applies only within the block of manip() as if they were declared in global scope.
  2. Ambiguity errors caused by using directives are detected when a name is used and not when the using directive is encountered. On the other hand, ambiguity errors caused by the more-specific using declarations are detected at the point of declaration.
  3. Qualified names is not affected by using directives. ::bj refer to global scope and blip::bj refer to namespace blip.
  4. Because the namespace members appear as if they were declared outside the namespace at the location where the namespace definition is located, local declarations will hide the namespace member names if they are same.

Therefore, if multiple using directives are declared, there might be name ambiguity errors. Errors can show up when adding new features (names) in the library. The global namespace pollution reappear.


Using namespace alias to associate an alternative, shorter or generic name with an existing namespace.identifiers. Potentially, an alias can also serve to encapsulate the actual namespace being used if the declarations within the two namespaces provide the exact interface. By changing the namespace assigned to the alias, the set of declarations are changed accordingly.
					
#include "Disney.h"
#include "Intel.h"
#include "AMD.h"

namespace DFA = Disney_Feature_Animation; // shorter alias
namespace LIB = Intel_Processor;	// generic alias

int main(void)
{
  DFA::Matrix i(1024);
  LIB::Processor();
  // ...
}

// Later,
namespace LIB = AMD_Processor;
int main(void)
{
  LIB::Processor();
  // ...
}

Use unnamed namespace to declare an entity local to a file, similar to those of a global entity declared static.
// file.cpp
namespace {
  // visible only within the file
  returntype1 Function1(parametertype1 parameter) { /* ... */ }
}

returntype2 Function2(parametertype2 parameter)
{
  // using Function1
  returntype1 r = Function1(p);
}

If another file contains an unnamed namespace with same definition of Function1, it is considered a different function.

Index