United States    
COMPAQ STORE | PRODUCTS |
SERVICES | SUPPORT | CONTACT US | SEARCH
cxxtitle.gif (12116 bytes)
Compaq C++

Compaq C++
Using Compaq C++ for Tru64 UNIX Systems


Previous Contents Index

5.2.10.3 Debugging Instantiations

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.

5.3 Manual Instantiation

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:

#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> > 

5.3.1 Using the define_template Command-Line Option

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); 
} 

5.3.2 Rules for Manually Instantiating Templates

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.

Internal Linkage

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.


Chapter 6
The C++ Standard Library

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.

6.2 How to Build Programs Using the C++ Standard Library

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:


cxx prog.cxx 

Thread Safety

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.

6.3 Incompatibilities Between the Compaq C++ Standard Library and the September 1996 ANSI C++ Draft

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.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; 
} 

6.4.2 Upgrading from the Nonstandard Compaq C++ Class Library

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:


Previous Next Contents Index
  

1.800.AT.COMPAQ

privacy and legal statement