Chapter 3: A first impression of C++

Don't hesitate to send in feedback: send an e-mail if you like the C++ Annotations; if you think that important material was omitted; if you find errors or typos in the text or the code examples; or if you just feel like e-mailing. Send your e-mail to Frank B. Brokken.

Please state the document version you're referring to, as found in the title (in this document: 7.2.2) and please state chapter and paragraph name or number you're referring to.

All received mail is processed conscientiously, and received suggestions for improvements will usually have been processed by the time a new version of the Annotations is released. Except for the incidental case I will normally not acknowledge the receipt of suggestions for improvements. Please don't interpret this as me not appreciating your efforts.

In this chapter C++ is further explored. The possibility to declare functions in structs is illustrated in various examples. The concept of a class is introduced.

3.1: More extensions to C in C++

Before we continue with the `real' object-approach to programming, we first introduce some extensions to the C programming language: not mere differences between C and C++, but syntactic constructs and keywords not found in C.

3.1.1: The scope resolution operator ::

C++ introduces several new operators, among which the scope resolution operator ( ::). This operator can be used in situations where a global variable exists having the same name as a local variable:
    #include <stdio.h>

    int counter = 50;                   // global variable

    int main()
    {
        for (register int counter = 1;  // this refers to the
             counter < 10;              // local variable
             counter++)
        {
            printf("%d\n",
                    ::counter           // global variable
                    /                   // divided by
                    counter);           // local variable
        }
        return 0;
    }
In this code fragment the scope operator is used to address a global variable instead of the local variable with the same name. In C++ the scope operator is used extensively, but it is seldom used to reach a global variable shadowed by an identically named local variable. Its main purpose will be described in chapter 6.

3.1.2: `cout', `cin', and `cerr'

Analogous to C, C++ defines standard input- and output streams which are opened when a program is executed. The streams are: Syntactically these streams are not used as functions: instead, data are written to streams or read from them using the operators <<, called the insertion operator and >>, called the extraction operator. This is illustrated in the next example:
    #include <iostream>

    using namespace std;

    int main()
    {
        int     ival;
        char    sval[30];

        cout << "Enter a number:" << endl;
        cin >> ival;
        cout << "And now a string:" << endl;
        cin >> sval;

        cout << "The number is: " << ival << endl
             << "And the string is: " << sval << endl;
    }
This program reads a number and a string from the cin stream (usually the keyboard) and prints these data to cout. With respect to streams, please note: The streams cin, cout and cerr are not part of the C++ grammar, as defined in the compiler which parses source files. The streams are part of the definitions in the header file iostream. This is comparable to the fact that functions like printf() are not part of the C grammar, but were originally written by people who considered such functions important and collected them in a run-time library.

Whether a program uses the old-style functions like printf() and scanf() or whether it employs the new-style streams is a matter of taste. The two styles can even be mixed. Some advantages are given below:

The iostream library has a lot more to offer than just cin, cout and cerr. In chapter 5 iostreams will be covered in greater detail. Even though printf() and friends can still be used in C++ programs, streams are practically replacing the old-style C I/O functions like printf(). If you think you still need to use printf() and related functions, think again: in that case you've probably not yet completely grasped the possibilities of stream objects.

3.1.3: The keyword `const'

Even though the keyword const is part of the C grammar, it is more important and much more common in C++ than it is in C.

The const keyword is a modifier which states that the value of a variable or of an argument may not be modified. In the following example the intent is to change the value of a variable ival, which fails:

    int main()
    {
        int const ival = 3;     // a constant int
                                // initialized to 3

        ival = 4;               // assignment produces
                                // an error message
    }
This example shows how ival may be initialized to a given value in its definition; attempts to change the value later (in an assignment) are not permitted.

Variables which are declared const can, in contrast to C, be used as the specification of the size of an array, as in the following example:

    int const size = 20;
    char buf[size];             // 20 chars big
Another use of the keyword const is seen in the declaration of pointers, e.g., in pointer-arguments. In the declaration
    char const *buf;
buf is a pointer variable, which points to chars. Whatever is pointed to by buf may not be changed: the chars are declared as const. The pointer buf itself however may be changed. A statement like *buf = 'a'; is therefore not allowed, while buf++ is.

In the declaration

    char *const buf;
buf itself is a const pointer which may not be changed. Whatever chars are pointed to by buf may be changed at will.

Finally, the declaration

    char const *const buf;
is also possible; here, neither the pointer nor what it points to may be changed.

The rule of thumb for the placement of the keyword const is the following: whatever occurs to the left to the keyword may not be changed.

Although simple, this rule of thumb is not often used. For example, Bjarne Stroustrup states (in http://www.research.att.com/~bs/bs_faq2.html#constplacement):

Should I put "const" before or after the type?

I put it before, but that's a matter of taste. "const T" and "T const" were always (both) allowed and equivalent. For example:

    const int a = 1;        // OK
    int const b = 2;        // also OK
My guess is that using the first version will confuse fewer programmers (``is more idiomatic'').
Below we'll see an example where applying this simple `before' placement rule for the keyword const produces unexpected (i.e., unwanted) results. Apart from that, the `idiomatic' before-placement conflicts with the notion of const functions, which we will encounter in section 6.2, where the keyword const is also written behind the name of the function.

The definition or declaration in which const is used should be read from the variable or function identifier back to the type indentifier:

``Buf is a const pointer to const characters''
This rule of thumb is especially useful in cases where confusion may occur. In examples of C++ code, one often encounters the reverse: const preceding what should not be altered. That this may result in sloppy code is indicated by our second example above:
    char const *buf;
What must remain constant here? According to the sloppy interpretation, the pointer cannot be altered (since const precedes the pointer). In fact, the charvalues are the constant entities here, as will be clear when we try to compile the following program:
    int main()
    {
        char const *buf = "hello";

        buf++;                  // accepted by the compiler
        *buf = 'u';             // rejected by the compiler

        return 0;
    }
Compilation fails on the statement *buf = 'u';, not on the statement buf++.

Marshall Cline's C++ FAQ gives the same rule (paragraph 18.5) , in a similar context:

[18.5] What's the difference between "const Fred* p", "Fred* const p" and "const Fred* const p"?

You have to read pointer declarations right-to-left.

Marshal Cline's advice might be improved, though: You should start to read pointer definitions (and declarations) at the variable name, reading as far as possible to the definition's end. Once you see a closing parenthesis, read backwards (right to left) from the initial point, until you find matching open-parenthesis or the very beginning of the definition. For example, consider the following complex declaration:
    char const *(* const (*ip)[])[]
Here, we see:

3.1.4: References

In addition to the well known ways to define variables, plain variables or pointers, C++ allows ` references' to be defined as synonyms for variables. A reference to a variable is like an alias; the variable and the reference can both be used in statements involving the variable:
    int int_value;
    int &ref = int_value;
In the above example a variable int_value is defined. Subsequently a reference ref is defined, which (due to its initialization) refers to the same memory location as int_value. In the definition of ref, the reference operator & indicates that ref is not itself an integer but a reference to one. The two statements
    int_value++;            // alternative 1
    ref++;                  // alternative 2
have the same effect, as expected. At some memory location an int value is increased by one. Whether that location is called int_value or ref does not matter.

References serve an important function in C++ as a means to pass arguments which can be modified. E.g., in standard C, a function that increases the value of its argument by five but returns nothing (void), needs a pointer parameter:

    void increase(int *valp)    // expects a pointer
    {                           // to an int
        *valp += 5;
    }

    int main()
    {
        int x;

        increase(&x)            // the address of x is
        return 0;               // passed as argument
    }
This construction can also be used in C++ but the same effect can also be achieved using a reference:
    void increase(int &valr)    // expects a reference
    {                           // to an int
        valr += 5;
    }

    int main()
    {
        int x;

        increase(x);            // a reference to x is
        return 0;               // passed as argument
    }
It can be argued whether code such as the above is clear: the statement increase (x) in the main() function suggests that not x itself but a copy is passed. Yet the value of x changes because of the way increase() is defined.

Actually, references are implemented using pointers. So, references in C++ are just pointers, as far as the compiler is concerned. However, the programmer does not need to know or to bother about levels of indirection. Nevertheless, pointers and references should be distinguished: once initialized, references can never refer to another variable, whereas the values of pointer variables can be changed, which will result in the pointer variable pointing to another location in memory. For example:

    extern int *ip;
    extern int &ir;

    ip = 0;     // reassigns ip, now a 0-pointer
    ir = 0;     // ir unchanged, the int variable it refers to
                // is now 0.

In order to prevent confusion, we suggest you adhere to the following:

References may result in extremely `ugly' code. A function may return a reference to a variable, as in the following example:
    int &func()
    {
        static int value;
        return value;
    }
This allows the following constructions:
    func() = 20;
    func() += func();
It is probably superfluous to note that such constructions should normally not be used. Nonetheless, there are situations where it is useful to return a reference. We have actually already seen an example of this phenomenon at our previous discussion of the streams. In a statement like cout << "Hello" << endl;, the insertion operator returns a reference to cout. So, in this statement first the "Hello" is inserted into cout, producing a reference to cout. Via this reference the endl is then inserted in the cout object, again producing a reference to cout. This latter reference is not further used.

A number of differences between pointers and references is pointed out in the list below:

3.2: Functions as part of structs

Earlier it was mentioned that functions can be part of structs (see section 2.5.14). Such functions are called member functions or methods. This section discusses how to define such functions.

The code fragment below illustrates a struct having data fields for a name and an address. A function print() is included in the struct definition:

    struct Person
    {
        char name[80],
        char address[80];

        void print();
    };
The member function print() is defined using the structure name (Person) and the scope resolution operator (::):
    void Person::print()
    {
        cout << "Name:      " << name << endl
                "Address:   " << address<< endl;
    }
In the definition of this member function, the function name is preceded by the struct name followed by ::. The code of the function shows how the fields of the struct can be addressed without using the type name: in this example the function print() prints a variable name. Since print() is a part of the struct person, the variable name implicitly refers to the same type.

This struct could be used as follows:

    Person p;

    strcpy(p.name, "Karel");
    strcpy(p.address, "Rietveldlaan 37");
    p.print();
The advantage of member functions lies in the fact that the called function can automatically address the data fields of the structure for which it was invoked. As such, in the statement p.print() the structure p is the `substrate': the variables name and address which are used in the code of print() refer to the same struct p.

3.3: Several new data types

In C the following basic data types are available: void, char, short, int, long, float and double. C++ extends these basic types with several new types: the types bool, wchar_t, long long and long double (Cf. ANSI/ISO draft (1995), par. 27.6.2.4.1 for examples of these very long types). The type long long is merely a double-long long datatype. The type long double is merely a double-long double datatype. Apart from these basic types a standard type string is available. The datatypes bool, and wchar_t are covered in the following sections, the datatype string is covered in chapter 4. Note that recent versions of C may also have adopted some of these newer data types (notably bool and wchar_t). Traditionally, however, C doesn't support them, hence they are mentioned in this section.

Now that these new types are introduced, let's refresh your memory about letters that can be used in literal constants of various types. They are:

3.3.1: The data type `bool'

In C the following basic data types are available: void, char, int, float and double. C++ extends these five basic types with several extra types. In this section the type bool is introduced.

The type bool represents boolean (logical) values, for which the (now reserved) values true and false may be used. Apart from these reserved values, integral values may also be assigned to variables of type bool, which are then implicitly converted to true and false according to the following conversion rules (assume intValue is an int-variable, and boolValue is a bool-variable):

        // from int to bool:
    boolValue = intValue ? true : false;

        // from bool to int:

    intValue = boolValue ? 1 : 0;
Furthermore, when bool values are inserted into, e.g., cout, then 1 is written for true values, and 0 is written for false values. Consider the following example:
    cout << "A true value: "  << true << endl
         << "A false value: " << false << endl;
The bool data type is found in other programming languages as well. Pascal has its type Boolean, and Java has a boolean type. Different from these languages, C++'s type bool acts like a kind of int type: it's primarily a documentation-improving type, having just two values true and false. Actually, these values can be interpreted as enum values for 1 and 0. Doing so would neglect the philosophy behind the bool data type, but nevertheless: assigning true to an int variable neither produces warnings nor errors.

Using the bool-type is generally more intuitively clear than using int. Consider the following prototypes:

    bool exists(char const *fileName);  // (1)
    int  exists(char const *fileName);  // (2)
For the first prototype (1), most people will expect the function to return true if the given filename is the name of an existing file. However, using the second prototype some ambiguity arises: intuitively the return value 1 is appealing, as it leads to constructions like
    if (exists("myfile"))
        cout << "myfile exists";
On the other hand, many functions (like access(), stat(), etc.) return 0 to indicate a successful operation, reserving other values to indicate various types of errors.

As a rule of thumb I suggest the following: if a function should inform its caller about the success or failure of its task, let the function return a bool value. If the function should return success or various types of errors, let the function return enum values, documenting the situation when the function returns. Only when the function returns a meaningful integral value (like the sum of two int values), let the function return an int value.

3.3.2: The data type `wchar_t'

The wchar_t type is an extension of the char basic type, to accomodate wide character values, such as the Unicode character set. The g++ compiler (version 2.95 or beyond) reports sizeof(wchar_t) as 4, which easily accomodates all 65,536 different Unicode character values.

Note that a programming language like Java has a data type char that is comparable to C++'s wchar_t type. Java's char type is 2 bytes wide, though. On the other hand, Java's byte data type is comparable to C++'s char type: one byte. Very convenient....

3.3.3: The data type `size_t'

The size_t type is not really a built-in primitive data type, but a data type that is promoted by POSIX as a typename to be used for non-negative integral values answering questions like `how much' and `how many', in which case it should be used instead of unsigned int. It is not a specific C++ type, but also available in, e.g., C. Usually it is defined implictly when a system header file is included. The header file `officially' defining size_t in the context of C++ is cstddef.

Using size_t has the advantage of being a conceptual type, rather than a standard type that is then modified by a modifier. Thus, it improves the self-documenting value of source code.

Sometimes functions explictly require unsigned int to be used. E.g., on amd-architectures the X-windows function XQueryPointer explicitly requires a pointer to an unsigned int variable as one of its arguments. In this particular situation a pointer to a size_t variable can't be used. This situation is exceptional, though.

Other useful bit-represented types also exists. E.g., uint32_t is guaranteed to hold 32-bits unsigned values. Analogously, int32_t holds 32-bits signed values. Corresponding types exist for 8, 16 and 64 bits values. These types are defined in the header file stdint.h.

3.4: Keywords in C++

C++'s keywords are a superset of C's keywords. Here is a list of all keywords of the language:
   and        const     float         operator static_cast    using
and_eq   const_cast       for               or      struct  virtual
   asm     continue    friend            or_eq      switch     void
  auto      default      goto          private    template volatile
bitand       delete        if        protected        this  wchar_t
 bitor           do    inline           public       throw    while
  bool       double       int         register        true      xor
 break dynamic_cast      long reinterpret_cast         try   xor_eq
  case         else   mutable           return     typedef
 catch         enum namespace            short      typeid
  char     explicit       new           signed    typename
 class       extern       not           sizeof       union
 compl        false    not_eq           static    unsigned
Note the operator keywords: and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor and xor_eq are symbolic alternatives for, respectively, &&, &=, &, |, ~, !, !=, ||, |=, ^ and ^=.

3.5: Data hiding: public, private and class

As mentioned before (see section 2.3), C++ contains special syntactic possibilities to implement data hiding. Data hiding is the ability of a part of a program to hide its data from other parts; thus avoiding improper addressing or name collisions.

C++ has three special keywords which are related to data hiding: private, protected and public. These keywords can be used in the definition of a struct. The keyword public defines all subsequent fields of a structure as accessible by all code; the keyword private defines all subsequent fields as only accessible by the code which is part of the struct (i.e., only accessible to its member functions). The keyword protected is discussed in chapter 13, and is beyond the scope of the current discussion.

In a struct all fields are public, unless explicitly stated otherwise. Using this knowledge we can expand the struct Person:

    struct Person
    {
        private:
            char d_name[80];
            char d_address[80];
        public:
            void setName(char const *n);
            void setAddress(char const *a);
            void print();
            char const *name();
            char const *address();
    };
The data fields d_name and d_address are only accessible to the member functions which are defined in the struct: these are the functions setName(), setAddress() etc.. This results from the fact that the fields d_name and d_address are preceded by the keyword private. As an illustration consider the following code fragment:
    Person x;

    x.setName("Frank");         // OK, setName() is public
    strcpy(x.d_name, "Knarf");  // error, x.d_name is private
Data hiding is implemented as follows: the actual data of a struct Person are mentioned in the structure definition. The data are accessed by the outside world using special functions, which are also part of the definition. These member functions control all traffic between the data fields and other parts of the program and are therefore also called `interface' functions. The data hiding which is thus implemented is illustrated in Figure 2.

Figure 2 is shown here.
Figure 2: Private data and public interface functions of the class Person.


Also note that the functions setName() and setAddress() are declared as having a char const * argument. This means that the functions will not alter the strings which are supplied as their arguments. In the same vein, the functions name() and address() return a char const *: the caller may not modify the strings to which the return values point.

Two examples of member functions of the struct Person are shown below:

    void Person::setName(char const *n)
    {
        strncpy(d_name, n, 79);
        d_name[79] = 0;
    }

    char const *Person::name()
    {
        return d_name;
    }
In general, the power of the member functions and of the concept of data hiding lies in the fact that the interface functions can perform special tasks, e.g., checking the validity of the data. In the above example setName() copies only up to 79 characters from its argument to the data member name, thereby avoiding array buffer overflow.

Another example of the concept of data hiding is the following. As an alternative to member functions which keep their data in memory (as do the above code examples), a runtime library could be developed with interface functions which store their data on file. The conversion of a program which stores Person structures in memory to one that stores the data on disk would not require any modification of the program using Person structures. After recompilation and linking the new object module to a new library, the program will use the new Person structure.

Though data hiding can be implemented with structs, more often (almost always) classes are used instead. A class refers to the same concept as a struct, except that a class uses private access by default, whereas structs use public access by default. The definition of a class Person would therefore look exactly as shown above, except for the fact that instead of the keyword struct, class would be used, and the initial private: clause can be omitted. Our typographic suggestion for class names is to use a capital character as its first character, followed by the remainder of the name in lower case (e.g., Person).

3.6: Structs in C vs. structs in C++

In this section we will illustrate the key difference between C and C++ structs. In C it is common to define several functions to process a struct, which then require a pointer to the struct as one of their arguments. A fragment of an imaginary C header file is given below:
    /* definition of a struct PERSON_   */
    typedef struct
    {
        char name[80];
        char address[80];
    } PERSON_;

    /* some functions to manipulate PERSON_ structs */

    /* initialize fields with a name and address    */
    void initialize(PERSON_ *p, char const *nm,
                       char const *adr);

    /* print information    */
    void print(PERSON_ const *p);

    /* etc..    */
In C++, the declarations of the involved functions are placed inside the definition of the struct or class. The argument which denotes which struct is involved is no longer needed.
    class Person
    {
        public:
            void initialize(char const *nm, char const *adr);
            void print();
            // etc..
        private:
            char d_name[80];
            char d_address[80];
    };
The struct argument is implicit in C++. A C function call such as:
    PERSON_ x;

    initialize(&x, "some name", "some address");
becomes in C++:
    Person x;

    x.initialize("some name", "some address");

3.7: Namespaces

Imagine a math teacher who wants to develop an interactive math program. For this program functions like cos(), sin(), tan() etc. are to be used accepting arguments in degrees rather than arguments in radians. Unfortunately, the function name cos() is already in use, and that function accepts radians as its arguments, rather than degrees.

Problems like these are usually solved by defining another name, e.g., the function name cosDegrees() is defined. C++ offers an alternative solution: by allowing us to use namespaces. Namespaces can be considered as areas or regions in the code in which identifiers are defined which normally won't conflict with names already defined elsewhere.

Now that the ANSI/ISO standard has been implemented to a large degree in recent compilers, the use of namespaces is more strictly enforced than in previous versions of compilers. This has certain consequences for the setup of class header files. At this point in the Annotations this cannot be discussed in detail, but in section 6.7.1 the construction of header files using entities from namespaces is discussed.

3.7.1: Defining namespaces

Namespaces are defined according to the following syntax:
    namespace identifier
    {
        // declared or defined entities
        // (declarative region)
    }
The identifier used in the definition of a namespace is a standard C++ identifier.

Within the declarative region, introduced in the above code example, functions, variables, structs, classes and even (nested) namespaces can be defined or declared. Namespaces cannot be defined within a block. So it is not possible to define a namespace within, e.g., a function. However, it is possible to define a namespace using multiple namespace declarations. Namespaces are called `open'. This means that a namespace CppAnnotations could be defined in a file file1.cc and also in a file file2.cc. The entities defined in the CppAnnotations namespace of files file1.cc and file2.cc are then united in one CppAnnotations namespace region. For example:

    // in file1.cc
    namespace CppAnnotations
    {
        double cos(double argInDegrees)
        {
            ...
        }
    }

    // in file2.cc
    namespace CppAnnotations
    {
        double sin(double argInDegrees)
        {
            ...
        }
    }
Both sin() and cos() are now defined in the same CppAnnotations namespace.

Namespace entities can be defined outside of their namespaces. This topic is discussed in section 3.7.4.1.

3.7.1.1: Declaring entities in namespaces

Instead of defining entities in a namespace, entities may also be declared in a namespace. This allows us to put all the declarations of a namespace in a header file which can thereupon be included in sources in which the entities of a namespace are used. Such a header file could contain, e.g.,
    namespace CppAnnotations
    {
        double cos(double degrees);
        double sin(double degrees);
    }

3.7.1.2: A closed namespace

Namespaces can be defined without a name. Such a namespace is anonymous and it restricts the visibility of the defined entities to the source file in which the anonymous namespace is defined.

Entities defined in the anonymous namespace are comparable to C's static functions and variables. In C++ the static keyword can still be used, but its use is more common in class definitions (see chapter 6). In situations where static variables or functions are necessary, the use of the anonymous namespace is preferred.

The anonymous namespace is a closed namespace: it is not possible to add entities to the same anonymous namespace using different source files.

3.7.2: Referring to entities

Given a namespace and entities that are defined or declared in it, the scope resolution operator can be used to refer to the entities that are defined in that namespace. For example, to use the function cos() defined in the CppAnnotations namespace the following code could be used:
    // assume the CppAnnotations namespace is declared in the
    // next header file:
    #include <CppAnnotations>

    int main()
    {
        cout << "The cosine of 60 degrees is: " <<
                CppAnnotations::cos(60) << endl;
    }
This is a rather cumbersome way to refer to the cos() function in the CppAnnotations namespace, especially so if the function is frequently used.

However, in these cases an abbreviated form (just cos()) can be used by specifying a using-declaration. Following

    using CppAnnotations::cos;  // note: no function prototype,
                                // just the name of the entity
                                // is required.
the function cos() will refer to the cos() function in the CppAnnotations namespace. This implies that the standard cos() function, accepting radians, cannot be used automatically anymore. The plain scope resolution operator can be used to reach the generic cos() function:
    int main()
    {
        using CppAnnotations::cos;
        ...
        cout << cos(60)         // uses CppAnnotations::cos()
            << ::cos(1.5)       // uses the standard cos() function
            << endl;
    }
Note that a using-declaration can be used inside a block. The using declaration prevents the definition of entities having the same name as the one used in the using declaration: it is not possible to use a using declaration for a variable value in the CppAnnotations namespace, and to define (or declare) an identically named object in the block in which the using declaration was placed:
    int main()
    {
        using CppAnnotations::value;
        ...
        cout << value << endl;  // this uses CppAnnotations::value

        int value;              // error: value already defined.
    }

3.7.2.1: The `using' directive

A generalized alternative to the using-declaration is the using-directive:
    using namespace CppAnnotations;
Following this directive, all entities defined in the CppAnnotations namespace are used as if they where declared by using declarations.

While the using-directive is a quick way to import all the names of the CppAnnotations namespace (assuming the entities are declared or defined separately from the directive), it is at the same time a somewhat dirty way to do so, as it is less clear which entity will be used in a particular block of code.

If, e.g., cos() is defined in the CppAnnotations namespace, the function CppAnnotations::cos() will be used when cos() is called in the code. However, if cos() is not defined in the CppAnnotations namespace, the standard cos() function will be used. The using directive does not document as clearly which entity will be used as the using declaration does. For this reason, the using directive is somewhat deprecated.

3.7.2.2: `Koenig lookup'

If Koenig lookup were called the `Koenig principle', it could have been the title of a new Ludlum novell. However, it is not. Instead it refers to a C++ technicality.

`Koenig lookup' refers to the fact that if a function is called without referencing a namespace, then the namespaces of its arguments are used to find the namespace of the function. If the namespace in which the arguments are defined contains such a function, then that function is used. This is called the `Koenig lookup'.

In the following example this is illustrated. The function FBB::fun(FBB::Value v) is defined in the FBB namespace. As shown, it can be called without the explicit mentioning of a namespace:

    #include <iostream>

    namespace FBB
    {
        enum Value        // defines FBB::Value
        {
            first,
            second,
        };

        void fun(Value x)
        {
            std::cout << "fun called for " << x << std::endl;
        }
    }

    int main()
    {
        fun(FBB::first);    // Koenig lookup: no namespace
                            // for fun()
    }
    /*
        generated output:
    fun called for 0
    */
Note that trying to fool the compiler doesn't work: if in the namespace FBB Value was defined as typedef int Value then FBB::Value would have been recognized as int, thus causing the Koenig lookup to fail.

As another example, consider the next program. Here there are two namespaces involved, each defining their own fun() function. There is no ambiguity here, since the argument defines the namespace. So, FBB::fun() is called:

    #include <iostream>

    namespace FBB
    {
        enum Value        // defines FBB::Value
        {
            first,
            second,
        };

        void fun(Value x)
        {
            std::cout << "FBB::fun() called for " << x << std::endl;
        }
    }

    namespace ES
    {
        void fun(FBB::Value x)
        {
            std::cout << "ES::fun() called for " << x << std::endl;
        }
    }

    int main()
    {
        fun(FBB::first);    // No ambiguity: argument determines
                            // the namespace
    }
    /*
        generated output:
    FBB::fun() called for 0
    */

Finally, an example in which there is an ambiguity: fun() has two arguments, one from each individual namespace. Here the ambiguity must be resolved by the programmer:

    #include <iostream>

    namespace ES
    {
        enum Value        // defines ES::Value
        {
            first,
            second,
        };
    }

    namespace FBB
    {
        enum Value        // defines FBB::Value
        {
            first,
            second,
        };

        void fun(Value x, ES::Value y)
        {
            std::cout << "FBB::fun() called\n";
        }
    }

    namespace ES
    {
        void fun(FBB::Value x, Value y)
        {
            std::cout << "ES::fun() called\n";
        }
    }

    int main()
    {
        /*
            fun(FBB::first, ES::first); // ambiguity: must be resolved
                                        // by explicitly mentioning
                                        // the namespace
        */
        ES::fun(FBB::first, ES::first);
    }
    /*
        generated output:
    ES::fun() called
    */

3.7.3: The standard namespace

Many entities of the runtime available software (e.g., cout, cin, cerr and the templates defined in the Standard Template Library, see chapter 17) are now defined in the std namespace.

Regarding the discussion in the previous section, one should use a using declaration for these entities. For example, in order to use the cout stream, the code should start with something like

    #include <iostream>
    using std::cout;
Often, however, the identifiers that are defined in the std namespace can all be accepted without much thought. Because of that, one frequently encounters a using directive, rather than a using declaration with the std namespace. So, instead of the mentioned using declaration a construction like
    #include <iostream>
    using namespace std;
is encountered. Whether this should be encouraged is subject of some dispute. Long using declarations are of course inconvenient too. So, as a rule of thumb one might decide to stick to using declarations, up to the point where the list becomes impractically long, at which point a using directive could be considered.

3.7.4: Nesting namespaces and namespace aliasing

Namespaces can be nested. The following code shows the definition of a nested namespace:
    namespace CppAnnotations
    {
        namespace Virtual
        {
            void *pointer;
        }
    }
Now the variable pointer is defined in the Virtual namespace, nested under the CppAnnotations namespace. In order to refer to this variable, the following options are available: At every using directive all entities of that namespace can be used without any further prefix. If a namespace is nested, then that namespace can also be used without any further prefix. However, the entities defined in the nested namespace still need the nested namespace's name. Only by using a using declaration or directive the qualified name of the nested namespace can be omitted.

When fully qualified names are somehow preferred and a long form like

        CppAnnotations::Virtual::pointer
is at the same time considered too long, a namespace alias can be used:
        namespace CV = CppAnnotations::Virtual;

This defines CV as an alias for the full name. So, to refer to the pointer variable, we may now use the construction

    CV::pointer = 0;
Of course, a namespace alias itself can also be used in a using declaration or directive.

3.7.4.1: Defining entities outside of their namespaces

It is not strictly necessary to define members of namespaces within a namespace region. By prefixing the member by its namespace or namespaces a member can be defined outside of a namespace region. This may be done at the global level, or at intermediate levels in the case of nested namespaces. So while it is not possible to define a member of namespace A within the region of namespace C, it is possible to define a member of namespace A::B within the region of namespace A.

Note, however, that when a member of a namespace is defined outside of a namespace region, it must still be declared within the region.

Assume the type int INT8[8] is defined in the CppAnnotations::Virtual namespace.

Now suppose we want to define a member function funny, inside the namespace CppAnnotations::Virtual, returning a pointer to CppAnnotations::Virtual::INT8. After first defining everything inside the CppAnnotations::Virtual namespace, such a function could be defined as follows (the examples below use the memory allocation operator new[] which will formally be introduced in chapter 7). At this point it can be assumed to behave somewhat like C's memory allocation function malloc():

    namespace CppAnnotations
    {
        namespace Virtual
        {
            void *pointer;

            typedef int INT8[8];

            INT8 *funny()
            {
                INT8 *ip = new INT8[1];

                for (int idx = 0; idx < sizeof(INT8) / sizeof(int); ++idx)
                    (*ip)[idx] = (idx + 1) * (idx + 1);

                return ip;
            }
        }
    }
The function funny() defines an array of one INT8 vector, and returns its address after initializing the vector by the squares of the first eight natural numbers.

Now the function funny() can be defined outside of the CppAnnotations::Virtual namespace as follows:

    namespace CppAnnotations
    {
        namespace Virtual
        {
            void *pointer;

            typedef int INT8[8];

            INT8 *funny();
        }
    }

    CppAnnotations::Virtual::INT8 *CppAnnotations::Virtual::funny()
    {
        INT8 *ip = new INT8[1];

        for (int idx = 0; idx < sizeof(INT8) / sizeof(int); ++idx)
            (*ip)[idx] = (idx + 1) * (idx + 1);

        return ip;
    }
In the final code fragment note the following:

Finally, note that the function could also have been defined in the CppAnnotations region. It that case the Virtual namespace would have been required when defining funny() and when specifying its return type, while the internals of the function would remain the same:

    namespace CppAnnotations
    {
        namespace Virtual
        {
            void *pointer;

            typedef int INT8[8];

            INT8 *funny();
        }

        Virtual::INT8 *Virtual::funny()
        {
            INT8 *ip = new INT8[1];

            for (int idx = 0; idx < sizeof(INT8) / sizeof(int); ++idx)
                (*ip)[idx] = (idx + 1) * (idx + 1);

            return ip;
        }
    }