6.2 Explicit Instantiation

Ru-Brd

The inclusion model ensures that all the needed templates are instantiated . This happens because the C++ compilation system automatically generates those instantiations as they are needed. The C++ standard also offers a construct to instantiate templates manually: the explicit instantiation directive .

6.2.1 Example of Explicit Instantiation

To illustrate manual instantiation, let's revisit our original example that leads to a linker error (see page 62). To avoid this error we add the following file to our program:

  // basics/myfirstinst.cpp  #include "myfirst.cpp"  // explicitly instantiate  print_typeof()  for type  double  template void print_typeof<double>(double const&); 

The explicit instantiation directive consists of the keyword template followed by the fully substituted declaration of the entity we want to instantiate. In our example, we do this with an ordinary function, but it could be a member function or a static data member. For example:

  // explicitly instantiate a constructor of  MyClass<>  for  int  template MyClass<int>::MyClass();  // explicitly instantiate a function template  max()  for  int  template int const& max (int const&, int const&); 

You can also explicitly instantiate a class template, which is short for requesting the instantiation of all its instantiatable members. This excludes members that were previously specialized as well as those that were already instantiated:

  // explicitly instantiate class  Stack<>  for  int  :  template class Stack<int>;  // explicitly instantiate some member functions of  Stack<>  for strings:  template Stack<std::string>::Stack();  template void Stack<std::string>::push(std::string const&);  template std::string Stack<std::string>::top();  // ERROR: can't explicitly instantiate a member function of a   //        class that was itself explicitly instantiated:  template Stack<int>::Stack(); 

There should be, at most, one explicit instantiation of each distinct entity in a program. In other words, you could explicitly instantiate both print_typeof<int> and print_typeof<double> , but each directive should appear only once in a program. Not following this rule usually results in linker errors that report duplicate definitions of the instantiated entities.

Manual instantiation has a clear disadvantage : We must carefully keep track of which entities to instantiate. For large projects this quickly becomes an excessive burden; hence we do not recommend it. We have worked on several projects that initially underestimated this burden , and we came to regret our decision as the code matured.

However, explicit instantiation also has a few advantages because the instantiation can be tuned to the needs of the program. Clearly, the overhead of large headers is avoided. The source code of template definition can be kept hidden, but then no additional instantiations can be created by a client program. Finally, for some applications it can be useful to control the exact location (that is, the object file) of a template instance. With automatic instantiation, this may not be possible (see Chapter 10 for details).

6.2.2 Combining the Inclusion Model and Explicit Instantiation

To keep the decision open whether to use the inclusion model or explicit instantiation, we can provide the declaration and the definition of templates in two different files. It is common practice to have both files named as header files (using an extension ordinarily used for files that are intended to be #include d), and it is probably wise to stick to this convention. (Thus, myfirst.cpp of our motivating example becomes myfirstdef.hpp , with preprocessor guards around the code inserted.) Figure 6.1 demonstrates this for a Stack<> class template.

Figure 6.1. Separation of template declaration and definition

graphics/06fig01.gif

Now if we want to use the inclusion model, we can simply include the definition header file stackdef.hpp . Alternatively, if we want to instantiate the templates explicitly, we can include the declaration header stack.hpp and provide a dot-C file with the necessary explicit instantiation directives (see Figure 6.2).

Figure 6.2. Explicit instantiation with two template header files

graphics/06fig02.gif

Ru-Brd


C++ Templates
C++ Templates: The Complete Guide
ISBN: 0201734842
EAN: 2147483647
Year: 2002
Pages: 185

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net