Bruce Eckel's Thinking in C++, 2nd Ed Contents | Prev | Next

Default arguments

Examine the two constructors for Stash( ). They don’t seem all that different, do they? In fact, the first constructor seems to be a special case of the second one with the initial size set to zero. It’s a bit of a waste of effort to create and maintain two different versions of a similar function.

C++ provides a remedy with default arguments. A default argument is a value given in the declaration that the compiler automatically inserts if you don’t provide a value in the function call. In the Stash example, we can replace the two functions:

  Stash(int size); // Zero quantity
Stash(int size, int quantity);

with the single function:

Stash(int size, int quantity = 0);

The Stash(int) definition is simply removed – all that is necessary is the single Stash(int, int) definition.

Now, the two object definitions

Stash A(100), B(100, 0);

will produce exactly the same results. The identical constructor is called in both cases, but for A, the second argument is automatically substituted by the compiler when it sees the first argument is an int and that there is no second argument. The compiler has seen the default argument, so it knows it can still make the function call if it substitutes this second argument, which is what you’ve told it to do by making it a default.

Default arguments are a convenience, as function overloading is a convenience. Both features allow you to use a single function name in different situations. The difference is that with default arguments the compiler is substituting arguments when you don’t want to put them in yourself. The preceding example is a good place to use default arguments instead of function overloading; otherwise you end up with two or more functions that have similar signatures and similar behaviors. If the functions have very different behaviors, it doesn’t usually make sense to use default arguments (for that matter, you might want to question whether two functions with very different behaviors should have the same name).

There are two rules you must be aware of when using default arguments. First, only trailing arguments may be defaulted. That is, you can’t have a default argument followed by a nondefault argument. Second, once you start using default arguments in a particular function call, all the subsequent arguments in that function’s argument list must be defaulted (this follows from the first rule).

Default arguments are only placed in the declaration of a function (typically placed in a header file). The compiler must see the default value before it can use it. Sometimes people will place the commented values of the default arguments in the function definition, for documentation purposes

void fn(int x /* = 0 */) { // ...

Placeholder arguments

Arguments in a function declaration can be declared without identifiers. When these are used with default arguments, it can look a bit funny. You can end up with

void f(int x, int = 0, float = 1.1);

In C++ you don’t need identifiers in the function definition, either:

void f(int x, int, float flt) { /* ... */ }

In the function body, x and flt can be referenced, but not the middle argument, because it has no name. Function calls must still provide a value for the placeholder, though: f(1) or f(1,2,3.0). This syntax allows you to put the argument in as a placeholder without using it. The idea is that you might want to change the function definition to use the placeholder later, without changing all the code where the function is called. Of course, you can accomplish the same thing by using a named argument, but if you define the argument for the function body without using it, most compilers will give you a warning message, assuming you’ve made a logical error. By intentionally leaving the argument name out, you suppress this warning.

More important, if you start out using a function argument and later decide that you don’t need it, you can effectively remove it without generating warnings, and yet not disturb any client code that was calling the previous version of the function.

Contents | Prev | Next


Contact: webmaster@codeguru.com
CodeGuru - the website for developers.
[an error occurred while processing this directive]