C++ – Name Visibility – Namespace – Using

Name Visibility

Named entities, such as variables, functions, and compound types need to be declared before being used in C++.

– An entity declared outside any block has global scope, meaning that its name is valid anywhere in the code.

– An entity declared within a block, such as a function or a selective statement, has block scope, and is only visible within the specific block in which it is declared.


int foo;        // global variable

int some_function ()
{
  int bar;      // local variable
  bar = 0;
}

int other_function ()
{
  foo = 1;  // ok: foo is a global variable
  bar = 2;  // wrong: bar is not visible from this function
}

Example:


// inner block scopes
#include <iostream>
using namespace std;

int main () {
  int x = 10;
  int y = 20;
  {
    int x;   // ok, inner scope.
    x = 50;  // sets value to inner x
    y = 50;  // sets value to (outer) y
    cout << "inner block:\n";
    cout << "x: " << x << '\n';
    cout << "y: " << y << '\n';
  }
  cout << "outer block:\n";
  cout << "x: " << x << '\n';
  cout << "y: " << y << '\n';
  return 0;
}

The result is:
inner block:
x: 50
y: 50
outer block:
x: 10
y: 50

Namespaces

Namespaces allow us to group named entities that otherwise would have global scope into narrower scopes, giving them namespace scope. This allows organizing the elements of programs into different logical scopes referred to by names.

The syntax is:

...
namespace myNamespace
{
  int a, b;
}
...
// Access at variables with:
myNamespace::a
myNamespace::b
...

Working example:


// namespaces
#include <iostream>
using namespace std;

namespace foo
{
  int value() { return 5; }
}

namespace bar
{
  const double pi = 3.1416;
  double value() { return 2*pi; }
}

int main () {
  cout << foo::value() << '\n';
  cout << bar::value() << '\n';
  cout << bar::pi << '\n';
  return 0;
}

The result is:
5
6.2832
3.1416

Using

The keyword using introduces a name into the current declarative region (such as a block), thus avoiding the need to qualify the name.


// using
#include <iostream>
using namespace std;

namespace first
{
  int x = 5;
  int y = 10;
}

namespace second
{
  double x = 3.1416;
  double y = 2.7183;
}

int main () {
  using first::x;
  using second::y;
  cout << x << '\n';
  cout << y << '\n';
  cout << first::y << '\n';
  cout << second::x << '\n';
  return 0;
}

The result is:
5
2.7183
10
3.1416

The keyword using can also be used as a directive to introduce an entire namespace:


// using
#include <iostream>
using namespace std;

namespace first
{
  int x = 5;
  int y = 10;
}

namespace second
{
  double x = 3.1416;
  double y = 2.7183;
}

int main () {
  using namespace first;
  cout << x << '\n';
  cout << y << '\n';
  cout << second::x << '\n';
  cout << second::y << '\n';
  return 0;
}

The result is:
5
10
3.1416
2.7183

‘using’ and ‘using namespace’ have validity only in the same block in which they are stated or in the entire source code file if they are used directly in the global scope. For example, it would be possible to first use the objects of one namespace and then those of another one by splitting the code in different blocks:


// using namespace example
#include <iostream>
using namespace std;

namespace first
{
  int x = 5;
}

namespace second
{
  double x = 3.1416;
}

int main () {
  {
    using namespace first;
    cout << x << '\n';
  }
  {
    using namespace second;
    cout << x << '\n';
  }
  return 0;
}

The result is:
5
3.1416

Reference: http://www.cplusplus.com/doc/tutorial/namespaces/