Topic : STL Newbie Guide
Author : Mumit Khan
Page : << Previous 10  
Go to page :


   for_each(list_iterator<int>, list_iterator<int>, FooBar)
   list<int>::~list(void)
   list<int>::begin(void)
   list<int>::end(void)
   back_insert_iterator<list<int> >::back_insert_iterator(list<int> &)
   deque<int>::~deque(void)
   deque<int>::push_back(int const &)
collect2: ld returned 2 exit status
gmake: *** [f2] Error 1


Now create our template-inst.cc file:


#include <stl.h>
#include <iostream.h>

template class list<int>;
template class list_iterator<int>;
template class back_insert_iterator<list<int> >;

template class ostream_iterator<int>;

template class deque<int>;
template class deque_iterator<int>;

template void copy(
    list_iterator<int>, list_iterator<int>, ostream_iterator<int>
);

template void copy(
    deque_iterator<int>, deque_iterator<int>, ostream_iterator<int>
);

template void copy(
    deque_iterator<int>, deque_iterator<int>, back_insert_iterator<list<int> >
);

struct FooBar {
    void operator() (int val) const {
        cout << " " << val;
    }
};
template void for_each(list_iterator<int>, list_iterator<int>, FooBar);



% g++ -fno-implicit-templates -c $(STL_INCLUDE_DIRS) f2.cc
% g++ -c $(STL_INCLUDE_DIRS) template-inst.cc
% g++ -o f2 f2.o template-inst.o $(STL_LIBS) |& c++filt
% ./f2

==> Deque1: 1103527590 377401575 662824084 1147902781 2035015474 368800899 1508029952 486256185 1062517886 267834847

==> List1: 1103527590 377401575 662824084 1147902781 2035015474 368800899 1508029952 486256185 1062517886 267834847

==> For_each List1:  1103527590 377401575 662824084 1147902781 2035015474 368800899 1508029952 486256185 1062517886 267834847

Using GCC 2.7.0 template repository mechanism
Let's start with a trivial program, where a list is the only STL data type used, specifically list<int>. For the examples here, I'm assuming ObjectSpace STL<ToolKit> with GCC 2.7.0 appropriately patched with Jason Merrill template frepo patch. It should also work just fine with any other STL implementation that happens to work with GCC.


A trivial example: building a simple standalone application
Providing library closure(s)

A trivial example: building a simple standalone application
Here's a trivial test program:

#include <stl.h>                // include everything for simplicity.
#include <iostream.h>
#include <stdlib.h>

int main(int, char*[]) {
    list<int> list1;
    for(int i = 0; i < 10; ++i) {
        list1.push_back(rand());
    }
    return 0;
}


Now running the following compile/link commands:
(STL_INCLUDE_DIRS and STL_LIBS depend on your system).

% g++ -frepo -c $(STL_INCLUDE_DIRS) f1.cc
% g++ -frepo -o f1 f1.o $(STL_LIBS)
collect: recompiling f1.cc
collect: relinking
collect: recompiling f1.cc
collect: relinking
collect: recompiling f1.cc
collect: relinking
%

And Voila! Granted, the first time you better go to lunch during build, but the subsequent times are much faster. How does it work? Quick answer: look in the build directory for f1.rpo and study it. You can get a good feel for what's happenning here by doing the following:

start afresh, ie., delete f1, f1.o and f1.rpo
simply compile f1.cc with the -frepo option and copy (not rename!) the resulting f1.rpo file to another file, say f1.rpo.org
build the executable f1 as in the example above and now compare the updated f1.rpo with your saved version). Notice that difference in the first column (the 'O's and the 'C's)
If you'd like a longer explanation, read the source code :-)

Providing library closure(s)
Let's say you're building a library with n C++ source files and you would like to provide template closure so that the clients do not have to worry about instantiating templates used in/by the library code. The simplest method is the following:

[
    build all the object files needed to build the library using the
    -frepo option
]
% gcc $(CPPFLAGS) $(CXXFLAGS) -frepo -o closure $(OBJS)
collect: recompiling xx.cc
collect: relinking
...
collect: recompiling xx.cc
collect: relinking
[
    Whole bunch of error messages about unresolved stuff -- ignore
]
% ar crv libxyz.a $(OBJS)
% ranlib libxyz.a


Here the link step forces the instantiation of the templates used within the library and rebuilds the .o files. Now the clients have to provide the instantiation for only those templates that library does not directly use.
[Thanks to Jason Merrill for this info]

This forced instantiation is fortunately quite extendible; consider the following case:

Application a needs to link with libraries l1 and l2.
Library l2 uses l1, and hence some of the templates in l2 are also instantiated in l1 if we build them separately using the method described in the previous paragraph.
The fix is quite simple:

Build l1 as in the example case above (ie., force the instantiation of all templates used within).
Build l2 with l1 on the command line.

% gcc $(CPPFLAGS) $(CXXFLAGS) -frepo -o closure $(L2_OBJS) libl1.a
collect: recompiling xx.cc
collect: relinking
...
collect: recompiling xx.cc
collect: relinking
[
    Whole bunch of error messages about unresolved stuff -- ignore
]
% ar crv libl2.a $(L2_OBJS)
% ranlib libl2.a


Now link the application with the two libraries, and you're in business.

An example combined <stl.h> file
//
// Suck in the entire (HP implementation derived) STL.
// This is very helpful for beginners, and one gets more familiar with
// STL, it's easy to figure out which headers to include. Also, different
// implementations might have different header names, eg., ObjectSpace
// has <algorith.h> and HP has <algo.h> Go figure.
//

#ifndef STL_H
#define STL_H

#include <algo.h>
#include <function.h>
#include <iterator.h>
#include <list.h>
#include <deque.h>
#include <map.h>
#include <pair.h>
#include <set.h>
#include <stack.h>
#include <vector.h>

#endif


Internet resources available
Free STL implementations:
SGI STL: Freely available STL implementation from SGI. Lots of useful links to other STL sites as well. A site to visit for all STL enthusiasts.
HP: This supposedly compiles with Borland C++ 4.5 out of the box. An alternate site is here .
FSF/GNU libg++ 2.6.2: Works with GCC 2.6.3 or newer. Based on Carsten Bormann's work.
FSF/GNU libg++ 2.7.0a: Works with GCC 2.7.0 or newer. Based on Carsten Bormann's work.
Bagnara: Another hacked STL based on HP implementation (modified GNU sources). Works with GCC 2.6.3 or newer.
C++ draft standard document:

HTML version of the DWP (courtesy of Mike Stump of Cygnus Support).
PDF and Postscript versions from Bell Labs ftp site.
Web pages/FTP sites with info on STL:


ObjectSpace examples: ObjectSpace has contributed over 300 examples to the public domain and these are a very good start for beginners.
Joseph Y. Laurino's STL page.
Musser's STL docs and examples. Very nice.
STL Newbie home site.
Marian Corcoran's STL FAQ.
Jak Kirman's STL Tutorial

Acknowledgments
Thanks to Kate Hedstrom and Adam Back for providing much of the motivation for turning this article into HTML. I am grateful to Jason Merrill and Mike Stump of Cygnus Support for informative posts in comp.lang.c++ and especially for answering my questions on how to use the -frepo switch with GCC 2.7.0. Some C++ code fragments were converted to HTML using c++2html written by Dimitry Kloper (dimka@tochna.technion.ac.il). The STL examples were contributed by ObjectSpace and can be found here .


For a GNU zipped tar copy of all files, click here (Warning: it's usually never quite up-to-date)-> URL:
http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.tar.gz
View the ChangeLog->URL:
http://www.xraylith.wisc.edu/~khan/software/stl/ChangeLog


Mumit Khan
khan@xraylith.wisc.edu
Last change: 13 Oct 1995

Notice:
There is a permission from the author, to publish this tutorial at www.cpp-home.com


Page : << Previous 10