How many instantiations of template there are? - c++

I've created Dynamic library project Foo and it has following code in the Foo.h:
#pragma once
#include <memory>
#ifdef MYLIB_EXPORTS
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#endif
class MYLIB_API Foo
{
};
template class MYLIB_API std::tr1::shared_ptr<Foo>;
typedef std::tr1::shared_ptr<Foo> FooPtr;
I use Foo class from my ConsoleApplication1:
#include "stdafx.h"
#include "Foo.h"
template class std::tr1::shared_ptr<Foo>; // (1)
int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
std::tr1::shared_ptr<Foo>(new Foo()); // (2)
return 0;
}
The code above is compiled without error/warnings. I use Visual Studio 2008 (v90) toolset to compile this. Both projects is compiled with /W4.
Questions:
1. Why (1) doesn't produce any compiler errors/warnings? I've expected here something like C2011 type redefinition. I suspect (1) is ignored.
2. How many instantiations of std::tr1::shared_ptr<Foo> there are? As it is compiled, I've expected that there two instantiation: one in the Foo and another in the consoleapplication1.
3. Which instantiation (if there are many) is used at (2)?
UPDATE1:
I compiled this with Assembly With Source Code (/FAs), and seems that both Foo and ConsoleApplication1 contain implementation of shared_ptr<Foo>. Doesn't this mean that there are two shared_ptr<Foo> explicit instantiation?

(1) isn't a redefinition, it's a forward declaration.
(2) There only needs to be one. I don't know why you expect any more. I supposed it's possible that a given compiler might produce more than one, but why? and it would figure pretty high on their bug list if it did.
(3) See (2).

Related

Is it possible to merge forward declaration and regular declaration into a single file, then use it as if they're separated?

I have this crazy idea of merging forward declaration headers and actual declaration files into one by performing some macro trickery. To provide some context, the daily policy I follow for forward declarations is as follows;
Each header file has its "_fwd.hpp" complement, which contains forward declarations of all forward-declarable entities in that header file.
I include the forward declaration header where forward-declaration of the actual thing suffices
I include the regular declaration header mainly in .cpp files and only when an actual implementation information is required (things requiring size of the implementation, inheritance etc.)
But having a separate _fwd.hpp header for each header pollutes the project, and is kind of hard to maintain. So, I come up with the following idea of merging forward declaration and actual declaration into single file, then enabling them according to include count. I come up with this initial idea of double-inclusion of header;
foo.hpp
#if !defined(FOO_FWD_H)
#define FOO_FWD_H
// Forward declarations goes here
struct foo;
#else // has forward_declaration, include actual if not included yet
#if !defined(FOO_H)
#define FOO_H
struct foo{
foo(){/*....*/}
};
// Normal declarations goes here
#endif // FOO_H
#endif // FOO_FWD_H
If I include "foo.hpp" once, I get forward declaration of foo, but if I include it second time in a translation unit, I get the forward & actual declaration of the foo, which is totally fine by me. (as I'm kinda doing the same thing anyway, include fwdecl in header, actual in cpp).
So, when put into use case described above, it goes like this;
bar.hpp
#pragma once
#include "foo.hpp" // forward declaration
struct bar{
bar(const foo& f);
};
bar.cpp
#include "bar.hpp" // bar + 1st inclusion of foo.hpp
#include "foo.hpp" // included 2nd time, actual implementation enabled
bar::bar(const foo& f){
f.rab(); // requires actual implementation
}
But as you can imagine, this approach has problems. The biggest issue is, if foo.hpp included by another header, tar.hpp, and tar.hpp is included in bar.hpp, causes actual implementation to be exposed to bar.hpp, defeating the purpose. Also, when actual implementation of foo.hpp is required in bar.hpp, it has to be included twice, which looks weird (linters and tools like iwyu might have an issue with that).
So the question boils down to this, can we actually make this work in such a way that;
including headers which using this idiom does not interfere with other headers' inclusion state
eliminating the need of double-inclusion when actual implementation is needed
Thanks in advance.
UPDATE: (30/10/19 10:57 PM GMT+2)
Improved version of idiom based on #IanAbbott 's answer:
Try it live : repl.it
foo.hpp (our single fwdecl & decl idiom implementing header)
// (mgilor): we got ourselves quite a lot boilerplate code,
// maybe x-macro concept help us to move away boilerplate to
// a separate file?
#if defined(FOO_FWD_ONLY)
#undef FOO_FWD_HPP // prevent accidental implementation inclusion on other headers
#endif
#if defined(FOO_FWD_ONLY) && !defined(FOO_FWD_HPP)
#define FOO_FWD_HPP
// forward declarations go here
struct foo;
#elif !defined(FOO_FWD_ONLY)
// includer wants the full monty
#if !defined(FOO_HPP)
#define FOO_HPP
// actual declarations go here
struct foo{
foo(){/*....*/}
void do_things(){}
};
#endif // FOO_HPP
#endif // FOO_FWD_HPP
// undef the macro, so future includes does not get affected
#undef FOO_FWD_ONLY
tar.hpp (fwdecl only consumer of foo)
#pragma once
#define FOO_FWD_ONLY
#include "foo.hpp" // this header needs forward declaration
#ifdef FOO_FWD_HPP
#pragma message ( __FILE__ " has forward declaration of foo")
#endif
#ifdef FOO_HPP
#pragma message ( __FILE__ " has full declaration of foo")
#endif
struct tar{
tar(foo & f){ }
};
bar.hpp (fwdecl only consumer of foo, also consumes tar.hpp)
#pragma once
#include "tar.hpp" // tar consumed foo fwdecl-only
#define FOO_FWD_ONLY
#include "foo.hpp" // bar needs fwdecl-only
#ifdef FOO_FWD_HPP
#pragma message ( __FILE__ " has forward declaration of foo")
#endif
#ifdef FOO_HPP
#pragma message ( __FILE__ " has full declaration of foo")
#endif
struct bar{
bar(foo & f);
};
bar.cpp (full decl consumer of bar & foo)
#include "bar.hpp"
#include "foo.hpp" // second inclusion, should enable full definition
#ifdef FOO_FWD_HPP
#pragma message ( __FILE__ " has forward declaration of foo")
#endif
#ifdef FOO_HPP
#pragma message ( __FILE__ " has full declaration of foo")
#endif
bar::bar(foo& ref){
ref.do_things();
}
baz.hpp (no dependencies)
#pragma once
struct baz{
void do_baz();
};
baz.cpp (full decl consumer of foo & baz)
#include "baz.hpp"
#include "foo.hpp" // no prior include of foo, but since FOO_FWD_ONLY is not defined
// baz.cpp will get full declaration.
#ifdef FOO_FWD_HPP
#pragma message ( __FILE__ " has forward declaration of foo")
#endif
#ifdef FOO_HPP
#pragma message ( __FILE__ " has full declaration of foo")
#endif
void baz::do_baz(){
foo f;
f.do_things(); // completely fine.
}
main.cpp (consuming application)
// consuming application
#include "tar.hpp"
#include "bar.hpp"
#include "foo.hpp" // already has previous foo fwdecl, so second inclusion will enable full declaration.
// (also FOO_FWD_ONLY is not defined, so first inclusion would enable it too)
#include "baz.hpp"
int main(void){
foo f;
tar t(f);
bar b(f);
baz bz;
}
Output when compiled:
tar.hpp:7:13: warning: tar.hpp has forward declaration of foo
bar.hpp:8:13: warning: bar.hpp has forward declaration of foo
bar.cpp:6:13: warning: bar.cpp has forward declaration of foo
bar.cpp:9:13: warning: bar.cpp has full declaration of foo
baz.cpp:9:13: warning: baz.cpp has full declaration of foo
tar.hpp:7:13: warning: tar.hpp has forward declaration of foo
bar.hpp:8:13: warning: bar.hpp has forward declaration of foo
Here is a proposal for consideration (maybe not the best). It involves the includer of an include file setting a macro to indicate that it only needs the forward declarations from that include file. When the macro is not defined, it gets everything from the include file. To avoid problems with header files forgetting to undefine the special macro afterwards, the file being included can be made responsible for undefining it.
It goes something like this:
foo.hpp
#if !defined(FOO_FWD_HPP)
#define FOO_FWD_HPP
// forward declarations go here
struct foo;
#endif // FOO_FWD_HPP
#if !defined(FOO_FWD_ONLY)
// includer wants the full monty
#if !defined(FOO_HPP)
#define FOO_HPP
// normal declarations go here
struct foo{
foo(){/*....*/}
};
#endif // FOO_HPP
#endif // FOO_FWD_ONLY
#undef FOO_FWD_ONLY
bar.hpp
#pragma once
// only need forward declarations from foo.hpp
#define FOO_FWD_ONLY
#include "foo.hpp"
struct bar {
bar(const foo& f);
};
bar.cpp
#include "bar.hpp"
#include "foo.hpp"
bar::bar(const foo& f){
f.rab(); // requires actual implementation
}
The main benefit is to reduce the amount of code being compiled. It does not do anything to fix the problem of unintended exposure. For example, if "bar.hpp" includes some other file that includes "foo.hpp" without defining the FOO_FWD_ONLY macro first, the full definitions from "foo.hpp" will be exposed to the remainder of "bar.hpp".

C++ template specialization in different dll produces linker errors

I have a third party dll that contains a template class with several specializations. I have my own specialization on Linux, trying to compile a windows dll however results in linker errors.
I tried around a bit and found out that the dllimport specification on the template header may be the cause and removing it would fix my problem. However I don't want to modify or copy the header since it could break with every update to the third party library.
Here is a minimal example to reproduce my problem
test.h - dll/so header:
#ifdef _WIN32
#ifdef EXPORT
# define LIB_EXPORT __declspec(dllexport)
#else
# define LIB_EXPORT __declspec(dllimport)
#endif
#else
# define LIB_EXPORT
#endif
template <typename A> class LIB_EXPORT Foobar
{
public:
virtual void helloWorld(){}
virtual ~Foobar(){}
};
test.cpp - dll/so impl:
#define EXPORT
#include "test.h"
template class __declspec(dllexport) Foobar<int>;
main.cpp - example program:
#include "test.h"
//explicit instanciation - does not help
template class __declspec(dllexport) Foobar<char>;
int main(int argc, char** argv)
{
Foobar<char> a;
a.helloWorld();
}
Is there a clean way to get a complete instantiation of Foobar in my executable ?
Compilers used: Visual Studio 2010, g++ mingw w64 4.9.1
I know you said that you dont want to modify the header since it could break the third party library updates, but the header that the template is defined in is not set up correctly. Hopefully you can get your vendor to modify their headers to be more import/export friendly.
The goal:
Define (export) a template specialization in a dll/so and then use (import) that specialization to your exe.
test.h
We dont want to only import or export every specialization of the template, so we remove the LIB_EXPORT from the class.
template <typename A> class Foobar {
...
}
We do want to import/export a specific specialization of the template however. We will forward declare the specialization and then explicitly instantiate it later in the compilation unit you want it to reside in.
Since you are also building with gcc, you will want to make use of the 'extern' keyword. Visual Studio 2010 does not implement it for templates.
#ifdef _WIN32
# define TEMPLATE_EXTERN
#ifdef EXPORT
# define LIB_EXPORT __declspec(dllexport)
#else
# define LIB_EXPORT __declspec(dllimport)
#endif
#else
# define TEMPLATE_EXTERN extern
# define LIB_EXPORT
#endif
The final forward declaration looks like
TEMPLATE_EXTERN template class LIB_EXPORT Foobar<int>;
test.cpp
We explicitly instantiate the template class here since our efforts in the header file have turned off the automatic instantiation features of the compiler.
#define EXPORT
#include "test.h"
template class Foobar<int>;
main.cpp
The default state of the headers is to implicitly instantiate the Foobar class with any type that is not int. The int specialization has been specifically tagged as 'export' on gcc and __declspec(dllimport) on win32. So you are able to make other specializations wherever you wish.
#include "test.h"
// explicit instantiation
template class Foobar<char>;
int main(int argc, char** argv)
{
Foobar<char> a;
a.helloWorld();
}

Define a macro then undefine it if it was previously undefined

I'm including header files which require certain pro-processor #defines to be present, however I do not want this to pollute the rest of my code e.g.:
// FOO may or may not already be defined here
#define FOO
#include "Bar.h"
#undef FOO
// FOO should be defined or not, as per the starting state
I'm thinking along the lines of:
#ifdef FOO
#define FOO_DEFINED
#endif
#define FOO
#include "Bar.h"
#ifndef FOO_DEFINED
#undef FOO
#else
#undef FOO_DEFINED
#endif
Questions:
Will the above work i.e. restore all macro definitions (or lack of) to the state they were in beforehand?
Is there perhaps a simpler solution?
Does it matter if FOO was already defined when I #define it? Should I add another #ifndef to protect against this?
It appears that in your example, Bar.h cares only whether FOO is defined or not, and not the actual expression bound to it. Furthermore, if someone else (I presume your code example is, itself, in a header file) defines FOO and cares about the expression bound to it, you don't want to make the mistake of redefining FOO with an empty expression. If so, you might want to simplify:
#ifndef FOO
#define FOO
#define UNDEF_FOO
#endif
#include "Bar.h"
#ifdef UNDEF_FOO
#undef FOO
#endif
yes it should work.
I have #pragma push_macro/pop_macro("macro_name") in mind, but it might work only in gcc and MS VC++
yes, it matters, you'll get a warning if it is defined again with a different value. As you state, you can shield it with #ifndef.

Template Linking and Separation of .h and .cc Files

I've been doing some reading into designing template code have a question about it. Most of the solutions to problems relating to designing code as templates seem to either be:
Put definitions of prototypes into the header file
Use the export keyword like this (which requires an extra compiler option)
Specifically lay out how the templates will be used in the .cc/.cpp file.
For example:
// File: foo_impl.cc
// We're working with Class Foo
#include "foo.cc"
template class Foo <int>;
template class Foo <string>;
// etc.
None of these methods seem very effective. Unless if I'm missing something, they don't seem to offer the ability for a user to simply import the header file and link the template code (in a .cc file) without doing extra work. I was wondering if people could take a look at what I'm doing with my own code and tell me if these violate some kind of best practices protocol or if they could cause an issue that I'm just not seeing. Here's what I've been doing...
In main.cc:
#include <iostream>
#include "foo.h"
using namespace std;
int main (void) {
Foo <string> f ("hello world");
string s = f.get ();
cout << s << endl;
return 0;
}
In foo.h:
#ifndef FOO_H
#define FOO_H
template <class T>
class Foo {
public:
Foo (T);
T get ();
private:
T data;
};
#endif
#include "foo.cc"
In foo.cc:
#ifndef FOO_CC
#define FOO_CC
#include "foo.h"
template <class T>
Foo :: Foo (T stuff) {
data = stuff;
}
template <class T>
T Foo <T> :: get () {
return data;
}
#endif
I've been able to compile the code with all warnings in gcc 4.1.2. Thank you!
I personally prefer to put the declaration (.h) in a separate file from the definition (your .cc file). Also, I'd avoid including the .cc file in the .h file. Methods in a .h file should only be inline methods.
Let's say in your example you also had a header file (bar.h) that simply declares a class that has a Foo data member.
Every time you would modify the definition of the Foo class, you would cause a recompile of anyone who includes bar.h, even tough they couldn't care less about the definition of Foo. However, bar.cpp is probably where you actually implement stuff and that file DOES need to include the implementation of your template. This seem trivial in small projects, but becomes a source of headaches in big projects that constantly recompile files for no reason. I've seen people throwing SSDs and Incredibuild at stuff that could be fixed by simple forward declares and better header management.
Personally, I use .imp.h for the implementation of my templates. Including cc files or cpp files seems yucky to me.
For example ( sorry for compilation errors. ;) )
// foo.h
#ifndef foo_h
#define foo_h
template< typename T >
struct Foo
{
Foo( T value );
void print();
T _value;
};
#endif
//foo.imp.h
#ifndef foo_imp_h
#define foo_imp_h
#include "foo.h"
#include <iostream>
template< typename T >
Foo< T >::Foo( T value ) : _value( value ) {}
void Foo< T >::print() { std::cout << _value << std::endl; }
#endif
// bar.h
#ifndef bar_h
#define bar_h
#include "foo.h"
struct Bar {
Foo< int > _intFoo;
Foo< double > _doubleFoo;
void print();
};
#endif
// bar.cpp
#include "bar.h"
#include "foo.imp.h"
void Bar::print()
{
_intFoo.print();
_doubleFoo.print();
}
// foobar.cpp
#include "bar.h"
void foobar()
{
Bar bar;
bar.print();
}
Had the defintion of foo be included in or by foo.h, bar.cpp and foobar.cpp would have been recompiled. Since only bar.cpp is concerned with Foo's implementation, splitting the defintion and declaration of Foo in two files and not having foo.h include foo.imp.h at the end saved me a recompile of foobar.cpp.
This is something that happens all the time in projects and can be very easily avoided by following the .h/.imp.h rule I explained above. The reason you never see this in stuff like STL or boost is because you are not modifying those files. It doesn't matter if they are in one or two files. But in your own projects, you will be constantly modifying the definitions of your templates and this is how you reduce recompilation times.
If you already know beforehand which types are actually going to be used with your template, than do not even bother with the .imp.h file. Put everything in a .cpp and do this at the end
// foo.cpp
// Implementation goes here.
// You might need to put something in front so that it gets exported from your DLL,
// depening on the platform
template class foo< int >;
template class foo< double >;
Lets start with basic ideology of .h and .cc files. When building libraries, the idea is to share only your header files and not your implementation (mean .cc files). This is also the basics OOP's encapsulation, abstraction etc, to hide the implementation details.
Now templates in C++ violates this principle, bcoz C++ is a compiled language. And compiler generates all the needed code during compilation. Now to adhere to OOP we end up with fragile templates which not 100% generic in nature.
Keep declaration and definitions separate (SHARING implementation)
If you are just want to keep things clean and in order, then you can include your implementation file in another header. I think it should be header file as this goes with basic convention that we share .h files and we keep .cc files not to be shared (until you are sharing the code itself). Here is how the files look.
foo.h
This is simple file with including foo_impl.h.
#ifndef FOO_H
#define FOO_H
template <class T>
class Foo {
public:
Foo (T);
T get();
private:
T data;
};
#include "foo_impl.h"
#endif
foo_impl.h
This one is bit different from the norms. Here we are not guarding the header file content. Instead we will raise an error if some one included foo_impl.h directly (which in our case does not make sense).
#ifndef FOO_H
#error 'foo_impl.h' is not supposed to be included directly. Include 'foo.h' instead.
#endif
template <class T>
Foo <T> :: Foo (T stuff) {
data = stuff;
}
template <class T>
T Foo <T> :: get () {
return data;
}
Now if some one tries to include foo_impl.h directly will get error like:
foo_impl.h:2:2: error: #error 'foo_impl.h' is not supposed to be included directly. Include 'foo.h' instead.
PROS:
Separation of concerns, implementation and declarations are in separate files.
Safe guarding implementation file avoid accidental inclusion.
The header file used to include is not bloated with implementation code.
CONS:
As mentioned above, have to share the implementation.
NOTE: For not sharing code for templates, I think you already know that you have to declare all possible types in the which the end user can use it.
Including .cc files is bad news and defeats the purpose of separating implementation from declaration.
Define templates in headers:
#ifndef FOO_H
#define FOO_H
template <class T>
class Foo {
public:
Foo (T);
T get ();
private:
T data;
};
// implementation:
template <class T>
Foo :: Foo (T stuff) {
data = stuff;
}
template <class T>
T Foo <T> :: get () {
return data;
}
#endif
If you really prefer 2 files then make the second one a .h too. Name it foo_impl.h or something.
It is common to affect the seperation of interface and implementation for templates by #includeing the implementation of the templates at the end of the header, but there are three problems with how you are doing it:
You're including the .h file in the .cc file. Don't; there should be nothing but function definitions in the implementation file.
You're .cc file should not be named .cc, it should be named .template or something similar to let people know that it should not be compiled (like headers should not be compiled)
The #include "foo.cc" in foo.h should be inside the include guards, not outside.
Done this way, there is no extra work for the user to be done. All you do is #include the header, and you're done. You don't compile the implementation.
Since you are including foo.cc in foo.h, you'll make your life simpler by putting all the code into foo.h and getting rid of foo.cc. There is no advantage to be gained from splitting the code into two pieces.
export keyword is deprecated in c++11. So, you will end up with deprecated code. You put your defintions in the header file itself.

Automatically separate class definitions from declarations?

I am using a library that consists almost entirely of templated classes and functions in header files, like this:
// foo.h
template<class T>
class Foo {
Foo(){}
void computeXYZ() { /* heavy code */ }
};
template<class T>
void processFoo(const Foo<T>& foo) { /* more heavy code */ }
Now this is bad because compile times are unbearable whenever I include one of those header files (and actually I include many of them in each of my compilation units).
Since as a template parameter I only use one or two types anyway I am planning to create, for each library header file, a file that contains only declarations, without the heavy code, like this:
// NEW: fwd-foo.h
template<class T>
class Foo {
Foo();
void computeXYZ();
};
template<class T>
void processFoo(const Foo<T>& foo);
And then one file that creates all the instantiations that I'll need. That file can be compiled separately once and for all:
// NEW: foo.cpp
#include "foo.h"
template class Foo<int>;
template class Foo<double>;
template void processFoo(const Foo<int>& foo);
template void processFoo(const Foo<double>& foo);
Now I can just include fwd-foo.h in my code and have short compile times. I'll link against foo.o at the end.
The downside, of course, is that I have to create these new fwd-foo.h and foo.cpp files myself. And of course it's a maintenance problem: When a new library version is released I have to adapt them to that new version. Are there any other downsides?
And my main question is:
Is there any chance I can create these new files, especially fwd-foo.h, automatically from the original foo.h? I have to do this for many library header files (maybe 20 or so), and an automatic solution would be best especially in case a new library version is released and I have to do this again with the new version. Are any tools available for this task?
EDIT:
Additional question: How can the newly supported extern keyword help me in this case?
We use lzz which splits out a single file into a separate header and translation unit. By default, it would normally put the template definitions into the header too, however, you can specify that you don't want this to happen.
To show you how you might use it consider the following:
// t.cc
#include "b.h"
#include "c.h"
template <typename T>
class A {
void foo () {
C c;
c.foo ();
b.foo ();
}
B b;
}
Take the above file and copy it to 't.lzz' file. Place any #include directives into separate $hdr and $src blocks as necessary:
// t.lzz
$hdr
#include "b.h"
$end
$src
#include "c.h"
$end
template <typename T>
class A {
void foo () {
C c;
c.foo ();
b.foo ();
}
B b;
}
Now finally, run lzz over the file specifying that it places the template definitions into the source file. You can either do this using a $pragma in the source file, or you can use the command line option "-ts":
This will result in the following files being generated:
// t.h
//
#ifndef LZZ_t_h
#define LZZ_t_h
#include "b.h"
#undef LZZ_INLINE
#ifdef LZZ_ENABLE_INLINE
#define LZZ_INLINE inline
#else
#define LZZ_INLINE
#endif
template <typename T>
class A
{
void foo ();
B b;
};
#undef LZZ_INLINE
#endif
And:
// t.cpp
//
#include "t.h"
#include "c.h"
#define LZZ_INLINE inline
template <typename T>
void A <T>::foo ()
{
C c;
c.foo ();
b.foo ();
}
#undef LZZ_INLINE
You can then run these through some grep/sed commands to remove the LZZ helper macros.
Try using precompiled headers. I know GCC and MSVC support this feature. Usage is vender-specific, though.
I have been working on the very same issue for quite a while now. In the solution you're proposing, you are defining your template classes twice. It will be ok if it defines the same stuff (in the same order), but you're bound to have problems sooner or later.
What i have come up with is to consider the problem the other way around. As long as you are not specializing your implementation, it works gracefully.
It uses two macros, which avois having to update template arguments in implementation file (be careful, though, if you want to add default template arguments to the class).
// foo.h
#define FOO_TEMPLATE template<typename T>
#define FOO_CLASS Foo<T>
FOO_TEMPLATE
class Foo {
Foo();
void computeXYZ();
};
// foo_impl.h
#include "foo.h"
FOO_TEMPLATE
FOO_CLASS::Foo(){}
FOO_TEMPLATE
void FOO_CLASS::computeXYZ() { /* heavy code */ }
By doing this, you essentially work the same way you do with non-template classes (you can do the same thing with template functions, of course).
EDIT : about the extern keyword in c++0x
I believe the extern keyword in c++0x will help, but it won't solve everything magically !
From this article,
Extern Templates
Every module that instantiates a
template essentially creates a copy of
it in the object code. Then, it's up
to the linker to dispose of all of the
redundant object code at the very last
stage, thus slowing the critical
edit-compile-link cycle that makes up
a programmer's day (or sometimes
daydreams). To short-circuit this
object code garbage collection, a
number of compiler vendors have
already implemented an extern keyword
that can go in front of templates.
This is a case of standardization
codifying existing industry practice
(pun intended). In practice, this is
implemented by sending a notice to the
compiler basically to "not instantiate
this here":
extern template class std::vector;
C++0x will fix your compile time issues with extern templates. I don't know an automatic way to do what you ask, though.