United States |
![]() |
![]() |
|
Previous | Contents | Index |
When you specify one of the -g options to
the cxx command, Compaq C++
instantiates any requested templates with this option as well. If the
application's binary file has moved with regard to the repository used
to build it, and a relative path name was specified to the -ptr command-line option, you must specify a
full repository path name to ensure that the debugger can find the
source files.
5.2.10.4 Linking Applications That Do Not Use Templates
By default, Compaq C++ performs the prelink steps associated with
automatic template instantiation. To avoid automatic template
instantiation, specify the -nopt option
to the cxx command.
Compaq C++ provides a mechanism for manual instantiation, using the
#pragma define_template directive. This
directive lets you tell the compiler what class or function template to
instantiate in conjunction with the actual arguments that the template
is to be instantiated with.
The #pragma define_template directive has
the following format:
5.3 Manual Instantiation
#pragma define_template identifier <template_arguments> |
identifier
Is the name of the class or function template that the compiler is directed to instantiate at compile time. For the instantiation to succeed, the definition of the template must appear before the #pragma define_template directive.template_arguments
Is a list of one or more actual types that correspond to the template parameters for the particular class or function template being instantiated. Whatever type is specified is used as the type for the instantiation.
The following is an example of a valid template manual instantiation:
//main.cxx template <class T> void sort (T*); int al[100]; float a2[100]; int main() { sort(a1); sort(a2); return 0; } //sort.cxx template <class T> void sort (T *array) { /* body of sort */ } #pragma define_template sort<int> #pragma define_template sort<float> |
To compile these sources, enter the following on the command line:
cxx main.cxx sort.cxx |
Sorting an array of template class elements requires the use of additional pragmas for the module sort.cxx. For example:
template <class T> void sort (T* array) { /*body of sort*/ } template <class T> class entity { public: T member; int operator < (const entity<T> &) const; } template <class T> int entity<T>::operator < (const entity<T> &operand) const { return member < operand.member; } int al[100]; float a2[100]; entity<int> a3[100]; #pragma define_template sort<int> #pragma define_template sort<float> #pragma define_template sort<entity<int> > void sort_all_arrays () { sort(a1); sort(a2); sort(a3); } |
Note that the define_template pragma is position sensitive. If a define_template pragma occurs lexically before a function, member function, or static data member template definition, the compiler will be unable to instantiate the corresponding template because the body of that template is not present prior to the pragma directive.
The compiler instantiates all instances of sort and of entity::operator < needed for this compilation unit.
To organize a program to use the define_template pragma, you can place the declarations of class and functions templates into header files, and instantiate all instances of a particular template from a single compilation unit. The following example shows how to do this:
// sort.h template <class T> void sort (T*); // entity.h template <class T> class entity { public: T member; int operator < (const entity<T> &) const; }; // main.cxx #include "sort.h" #include "entity.h" int al[100]; float a2[100]; entity<int> a3[100]; int main() { sort(a1); sort(a2); sort(a3); return 0; } // sort.cxx #include "sort.h" #include "entity.h" template <class T> void sort (T* array) { /*body of sort*/ } #pragma define_template sort<int> #pragma define_template sort<float> #pragma define_template sort<entity<int> > |
Compiling the following file provides a definition of entity::operator < with type int:
// entity.cxx #include "entity.h" template <class T> int entity<T>::operator < (const entity<T> &operand) const { return member < operand.member; } #pragma define_template entity<int> |
To compile this example, issue the following command:
cxx main.cxx sort.cxx entity.cxx |
If the program uses other instantiations of entity in other compilation units, you can provide definitions of operator < for those entities by adding define_template pragmas to entity.cxx. For example, if other compilation units use entity<long> and entity< entity<int> >, appending the following pragmas to entity.cxx causes the compiler to generate instantiations of operator < for those requests of entity:
#pragma define_template entity<long> #pragma define_template entity< entity<int> > |
Alternatively, you could use the -define_templates command-line option to instantiate templates. Using the -define_templates option requires the same template definition and compilation procedures as previously described for the define_template pragma. For a description of the -define_templates option on the cxx command, see the cxx(1) reference page.
Considering the examples previously presented in this section, you can use this qualifier to supply definitions of sort<int>, sort<float>, and sort<entity<int> > by compiling the following file:
// sort.cxx #include "sort.h" #include "entity.h" template <class T> static sort (T* array) { /*body of sort*/ } static void function_never_used () { int al[100]; float a2[100]; entity<int> a3[100]; sort(a1); sort(a2); sort(a3); } |
For a function template, instantiating the template means interpreting the body of the function template using a specific set of template arguments.
For a class template, instantiating the template means making the following interpretations using a specific set of template arguments:
Consider the following example:
template <class A, class B> class tag { void foo(void); void bar(void); } template <class A, class C> void tag<A, C>::foo (void) {} #pragma define_template tag<int, int> template <class A, class B> void tag<A, B>::bar (void) {} |
When compiling this code, Compaq C++ does not define tag<int, int>::foo because tag and tag::foo have different template parameters. The compiler does not instantiate tag<int, int>::bar because tag::bar is defined after tag<int, int> is instantiated.
Compaq C++ automatically instantiates template functions from templates that define functions with internal linkage. When the following conditions are met, no further user action is required to instantiate template functions:
In the following example, the compiler takes care of instantiating all required instances of sort and entity::operator <:
template <class T> static void sort (T* array) { /*body of sort*/ } template <class T> class entity { public: T member; int operator < (const entity<T> &operand) const { return member < operand.member; } }; |
Defining template functions inline is practical only for very small functions. Compaq C++ replicates an inline function in each compilation unit that uses it, so defining large functions inline can substantially increase the size of a program's object code.
Compaq C++ currently provides a partial implementation of the C++ Standard Library. The ANSI X3/J16 C++ committee is in the process of standardizing the C++ Standard Library, and when this process is complete, Compaq C++ will provide a complete library implementation. In the meantime, the subset provided was selected from among the most stable parts of the library as defined in the ANSI C++ draft.
This release of Compaq C++ contains the following components of the C++ Standard Library:
Some of the components in the C++ Standard Library are designed to replace nonstandard components that are currently distributed in the Compaq C++ Class Library. Compaq will continue to provide the Compaq C++ Class Library in its nonstandard form. However, you now have the option of using the new standard components.
The following sections provide more information on the Compaq C++
implementation of the Standard Library, including upward compatibility,
compiling and linking, thread safety, and details on each component of
the library.
6.1 Important Compatibility Information
Because the standardization process for the C++ Standard Library is not yet completed, Compaq cannot guarantee that this version of the library is compatible with any past or future releases. We ship the run-time portion of the library in object form, not in shareable form, to emphasize this situation.
Therefore, Compaq recommends that you do not use this library for any
production code that requires upward compatibility. This release of the
library matches as closely as is feasible the standard described in the
post-Stockholm ANSI C++ draft dated 24 September 1996.
When you use the cxx command to compile
and link programs that use the C++ Standard Library, no special
switches are required. The Compaq C++ driver automatically includes
the Standard Library run-time support (-lcxxstd) on the link command, and automatic
template instantiation (-pt) is the
default mode.
For example, to build a program called prog.cxx that uses the Standard Library, you
can simply use the following command:
6.2 How to Build Programs Using the C++ Standard Library
cxx prog.cxx |
The C++ Standard Library is thread safe if you specify the -D_REENTRANT flag on your cxx command. You can also use the -threads flag to establish thread safety. This
ensures that all internal library data is protected against
simultaneous access from multiple threads.
Compaq C++ currently does not support all the necessary language
features to compile a Standard Library that meets the specifications of
the ANSI C++ draft. Therefore, where possible, the Compaq
implementation of the Standard Library contains workarounds for these
missing language features.
The following list shows the unsupported ANSI C++ language features and
their workarounds in the Compaq C++ Standard Library:
The following data structures and algorithms supplied with the current
STL differ from those specified in the September 1996 ANSI C++ draft:
Additionally, the following are some minor incompatibilities in the
current String Library that correct what Compaq believes are mistakes
in the draft:
6.3 Incompatibilities Between the Compaq C++ Standard Library and the September 1996 ANSI C++ Draft
Athough the current version of the Compaq C++
compiler offers this support, the Standard Library classes and
functions are not placed in namespace std.
Some member function templates
within the Standard Library have been substituted with member functions
for a given type.
The current STL simulates bool as a typedef of int.
Thus, the Compaq C++ STL cannot supply the specialization vector<bool> because it would conflict
with vector<int>. In the interim,
Compaq supplies a bit_vector class in
place of vector<bool>.
The Compaq C++ compiler does not support
wchar_t as a built-in type, therefore the
current String Library does not support wide character types.
The Compaq C++ Numeric Limits class does not
provide a specialization for bool or for wchar_t because Compaq C++ does not treat
them as built-in types.
Compaq C++ does not support the mutable keyword, thus the auto_ptr release() member is not declared const.
6.4 The Standard Template Library
Compaq C++ provides an implementation of the Standard Template Library (STL).
The following sections provide information specific to the
Compaq C++ implementation of the STL. For information on how to
program with the STL, refer to the STL Tutorial and Reference
Guide that is part of the Compaq C++ printed documentation set.
See Section 6.4.3 for differences between the STL Tutorial and
Reference Guide and the Compaq C++ implementation of the STL.
6.4.1 Examples of Use
The following are some simple examples of using the containers and algorithms in the STL. You should compile these examples with the command:
cxx prog.cxx |
For details on how to build programs that use the STL, see Section 6.2.
Using the vector class
// This example shows how to create a vector, // initialize it with values, sort and print it #include <vector> #include <algorithm> #include <iostream.hxx> int main() { // create a vector of 4 ints vector<int> v(4); // initialize the vector with values v[0]=2; v[1]=0; v[2]=3; v[3]=1; // sort the vector sort(v.begin(),v.end()); // print the sorted vector for (vector<int>::iterator viter=v.begin();viter!=v.end();viter++) cout << *viter << " "; cout << endl; return 0; } |
Using the list class
// This example shows how to create a list, initialize // it with values, find a particular value and print // the element before and after that value #include <list> #include <iostream.hxx> #include <string> int main() { // create a list list<string> l; // add some values to the list l.insert(l.end(),"Stepanov"); l.insert(l.end(),"Koenig"); l.insert(l.end(),"Stroustrup"); l.insert(l.end(),"Lippman"); // find the value "Stroustrup" string value("Stroustrup"); list<string>::iterator liter=find(l.begin(),l.end(), value); // print out the value before and after "Stroustrup" if (liter!=l.end()) cout << "Stroustrup was found after " << *(--liter) << " and before " << *(++(++liter)) << endl; return 0; } |
Using the map class
// This example shows how to create a map, // add some values, and find the number of elements // which match a specified criterion #include <map> #include <iostream.hxx> bool smaller (pair<const char* const, float> p) { // returns true if element costs less than $3.00 return p.second < 3.00; } int main() { // create a map map<const char*,float, less<const char*> > shopmap; // add some elements to the map shopmap["milk"]=1.29; shopmap["steak"]=5.99; shopmap["cornflakes"]=2.69; shopmap["cheese"]=3.42; shopmap["ricekrispies"]=2.25; // count the number of items less than $3.00 int num_items = 0; count_if(shopmap.begin(),shopmap.end(),smaller,num_items); // print the results cout << "number of items less than 3 dollars is: " << num_items << endl; return 0; } |
The following discussion guides you through upgrading Compaq C++
Class Library code to use the STL, specifically replacing the vector
and stack classes that are currently in the vector.hxx header file.
6.4.2.1 Upgrading from the Compaq C++ Class Library Vector to the STL Vector
To change your code from using the Compaq C++ Class Library vector to the STL vector, consider the following actions:
Nonstandard Vector Function | Replaced with STL Vector Function |
---|---|
elem(int index) |
operator[](size_t index)
(no bounds checking) |
operator[](int index) |
at(size_t index)
(bounds checking) |
setsize(int newsize) | resize(size_t newsize) |
Previous | Next | Contents | Index |
|