Previous Table of Contents Next


After several false starts, a facility for defining and using namespaces was introduced into C++ in 1994. In the standards committee, the initial impetus came from a proposal written by Keith Rowe from Microsoft. By early 1993, I had—with the help of multimegabyte email exchanges and discussions at the standards meetings—synthesized a coherent proposal. I recall technical contributions on namespaces from Dag Bruck, John Bruns, Steve Dovich, Bill Gibbons, Philippe Gautron, Tony Hansen, Peter Juhl, Andrew Koenig, Eric Krohn, Doug McIlroy, Richard Minner, Martin O’Riordan, John Skaller, Jerry Schwarz, Mark Terribile, and Mike Vilot.

The basic idea is simple: A name can be declared in a named scope—called a namespace—and to use a name from outside its namespace, some explicit action is needed. By default, this eliminates name clashes. The problem is to make access so convenient that people do not reject namespaces as not worth the effort to use them.

For example, here are some facilities for dealing with time that have been defined in their own namespace Chrono to establish the fact that they constitute a logical explicit unit and to avoid name clashes:

   namespace Chrono { // facilities for dealing with time

       class Date {
        // ...
       };

       int operator-(Date a, Date b);
       bool leapyear(int y);
       Date next_weekday(Date d);
       Date next_saturday(Date d);

       class Time {
           // ...
       };

       // ...
   }

A programmer can refer to a name from a namespace by explicit qualification:

   void f(Chrono::Date d)
   {

       Chrono::Date monday = Chrono::next_saturday(d).add_day(2);
       // ...
   }

However, I saw no hope of programmers accepting a notation that verbose and redundant. In particular, there would be no way of gradually introducing namespaces into existing programs. Consequently, we provided mechanisms for making a namespace name implicit. A using declaration introduces a local synonym into a scope:

   using Chrono::Date; // Date is Chrono::Date

   void f(Date d)
   {
       Date monday = Chrono::next_saturday(d).add_day(2);
       // ...
   }

A using directive is a somewhat more powerful and therefore potentially more dangerous mechanism that makes every name from a namespace available in a scope:

   void g(Chrono::Date d)
   {
       using namespace Chrono; // make Chrono names available

       Date monday = next_saturday(d).add_day(2);
   }

The using directive is intended primarily to smooth the introduction of namespaces into existing programs where there is no explicit mention of namespaces.

Andrew Koenig observed that in many cases, no explicit resolution mechanism was needed if we resolved a function call or the use of an operator based on the namespace (or namespaces) of the operands. Here’s an example:

   void f(Chrono::Date d)
   {
       Chrono::Date monday = next_saturday(d).add_day(2);
       if (monday-d < 2) {
           // ...
       }
       // ...
   }

Here, next_saturday() and the operator defined in Chrono are used because those are the ones logically connected with the operands by being declared in Chrono. For further details, see The Design and Evolution of C++ (Stroustrup, 1994) and The C++ Programming Language, Third Edition (Stroustrup, 1997).

6.5.8. Runtime Type Identification

In the original C++ design, I deliberately didn’t include the Simula mechanisms for runtime type identification (QUA and INSPECT). In my experience, they were almost always misused so that the benefits from having the mechanism would be outweighed by the disadvantages. However, in large systems composed of separately developed parts, it is often unavoidable that information is passed around in ways that renders their exact type unknown. Thus, I reluctantly accepted that the time to introduce a mechanism for runtime type identification had come. The immediate impetus was work by Dmitry Lenkov and his colleagues at HP (Lenkov, Mehta, & Unni, 1991). Lenkov and I developed a proposal for a standard mechanism for runtime type identification where the primary operation is a runtime-checked pointer conversion. Here’s an example:

   void my_fct(Dialog_box* bp)
   {
       if (My_dbox* dbp = dynamic_cast<My_dbox*>(bp)) {

           // use dbp
       }
       else {

           // treat *pb as a “plain” dialog box
       }
   }

The dynamic_cast<My_dbox*>(bp) operator converts its operand bp to the desired type My_dbox* if *bp really is a My_dbox or a class derived from My_dbox; otherwise, the value of dynamic_cast<My_dbox*>(bp) is 0.

Thus, the dynamic_cast operator combines a test of the actual type of the object taking inheritance into account (like Smalltalk’s isKindOf) with a pointer conversion. For a language that relies on static type checking, the conversion is necessary, and not taking inheritance into account would render the operation clumsy and error-prone. The use of an “ugly” conversion notation and the absence of a type-switch statement (like Simula’s INSPECT) is intended to minimize (mis)use of runtime type information to write programs that violate modularity by centralizing information about otherwise unrelated types in type switches.

For further details, see The Design and Evolution of C++ (Stroustrup, 1994) and The C++ Programming Language, Third Edition (Stroustrup, 1997).


Previous Table of Contents Next