In order to reduce compilation time in a large project that uses liberal use of templates, I had good results using the extern template ( explicit template creation ) to prevent the use of common template functions in many different compilation units.
However, one of the unpleasant things is that it does not work for the member functions defined in the class definition.
For example, I have the following class of templates:
template <typename T> struct Foo { static T doubleIt(T input) { return input * 2; } };
Now I know that Foo is most often used for numeric types, so I add this to the header:
extern template struct Foo<int>; extern template struct Foo<float>; extern template struct Foo<double>;
And in the cpp file add explicit instances:
template struct Foo<int>; template struct Foo<float>; template struct Foo<double>;
This does not work, since dumpbin.exe in the obj file tells me:
017 00000000 SECT4 notype () External | ?doubleIt@ ?$Foo@M @@ SAMM@Z (public: static float __cdecl Foo<float>::doubleIt(float))
If I changed the class definition to define a function outside the class header, so that it works correctly:
template <typename T> struct Foo { static T doubleIt(T input); }; template <typename T> T Foo::doubleIt(T input) { return input * 2; }
What we can check with dumpbin:
017 00000000 UNDEF notype () External | ?doubleIt@ ?$Foo@M @@ SAMM@Z (public: static float __cdecl Foo<float>::doubleIt(float))
The problem with this solution is that there is a lot of need to move all function definitions outside the class definition, especially when you get more template parameters.
I tried using declspec (__ noinline), but it still does not execute functions correctly (and prevents unwanted inlining of the function, if possible).
One thing that works is to list each function individually, for example, but this, of course, is even more cumbersome:
extern template int Foo<int>::doubleIt(int); extern template float Foo<float>::doubleIt(float); extern template double Foo<double>::doubleIt(double);
What I would like is a way to keep the function definition inside the class definition, while retaining the ability to be inline, if possible, but when it is not inline, only create it in the compilation unit, where it is explicit (in other words, exactly the same behavior, like moving a function outside a class definition).