In current g++, I typically include all my templated functions that take the template parameter as an argument because they have to be compiled for each instance.
template<typename T>
class A {
public:
void f() { ... }
};
So in a different source, I would write:
#include <A.hh>
A<int> a1;
a1.f();
A<double> a2;
a2.f();
Sometimes, w开发者_开发问答hen I've been desperate to not inline big methods, I've manually specified which classes will be used in the source file, but it's really obnoxious:
template<typename T>
A::A() { ... }
template<typename T>
void A::f() { ... }
A<int>; // manually trigger code generation for int and double
A<double>;
Obviously different IDEs and compilers have mechanisms to support this. Is there anything standard that has been mandated, and/or does g++ support anything like this?
There's nothing in the proposed C++0x standard. In fact, export template
has been removed (few compilers implemented it anyway).
As far as inlining is concerned, it's a total non-issue. The compiler is smart enough not to inline functions which are too big, even if they're marked inline
and put into a header file.
If you're looking at increased compile times from header files grown bloated from templates, use precompiled headers. These aren't standard, but almost all current compilers provide such a mechanism.
C++0x does have extern template
, which allows you to prevent the instantiation of certain templates in a compilation unit. So if you have a template class SomeClass
, you can put this in the header:
extern template SomeClass<int>;
extern template SomeClass<double>;
This will prevent users from instantiating the template. In the .cpp file for the template, you can force instantiation with this syntax:
template SomeClass<int>;
template SomeClass<double>;
I've manually specified which classes will be used in the source file, but it's really obnoxious:
A<int>; // manually trigger code generation for int and double
A<double>;
This is not legal (I assume you meant to declare dummy variables here, and missed their name). We will see below why
Is there anything standard that has been mandated, and/or does g++ support anything like this?
C++03 had something called export
, but which turned out to be a misfeature. The EDG implemented that feature, and their experience with it indicated that it's not worth the trouble implementing it. And it doesn't provide a useful feature separate compilation usually gives you: Hiding of the code of templates which you once compiled. export
still requires the code of templates, be it in raw form or encoded into a mid-level compiler-specific language. See Why we can't afford export. A short example is given by EDG worker David Vandevoorde here.
For C++0x and for C++0x sans export, we have
A function template, member function of a class template, or static data member of a class template shall be defined in every translation unit in which it is implicitly instantiated (14.7.1) unless the corresponding specialization is explicitly instantiated (14.7.2) in some translation unit; no diagnostic is required
As this indicates, the only way you can achieve separate compilation is to explicitly instantiate the template you want to have separately compiled. By defining dummy variables, you merely implicitly instantiate the class template. And you do not instantiate the member functions of the class templates that way - you would need to do dummy calls or take their address. And to all this, you are not guaranteed that an implicitly instantiated function won't be discarded if it's not used in the translation unit it was instantiated by, after optimization, based on the above quote.
So you explicitly instantiate the class template, which will explicitly also instantiate its member functions the following way:
template class A<int>;
template class A<double>;
This feature, called export
is present even in the current standard of C++. Unfortunately, most compilers, including gcc, do not support it. See here http://gcc.gnu.org/bugs/
精彩评论