So a colleague and I have been debating the benefits of explicit template instantiation when it comes to reducing compile time, separating declaration from definition, and not affecting performance of a C++ math library I have written that is used for other projects.
Essentially I have a library of useful math functions designed to work with primitives like Vector3, Vector4, Quaternion, etc.. All of which are meant to be used with the template argument being float or double (and in some instances int).
So that I do not have to write these functions twice, once for floats once for double, the function implementations are templated, like so:
template<typename T>
Vector3<T> foo(const Vector4<T>& a,
const Quaternion<T>& b)
{ do something... }
All defined in .h files (so they are implicitly marked for inlining). Most of these function are short and are hoped to be inlined during usage compilation.
Headers are getting pretty big though, compile times are going up, and its getting hard to find the existence of functions by just glancing at the headers (that's one of the many reasons I like separating declaration from implementations).
So I can use explicit template instantiation in an accompanying .cpp file, like so:
//in .h
template<typename T>
Vector3<T> foo(const Vector4<T>& a,
const Quaternion<T>& b)
{ do something... }
//in .cpp
template Vector3<float> foo<float>(const Vector4<float>& a,
const Quaternion<float>& b);
template Vector3<double> foo<double>(const Vector4<double>& a,
const Quaternion<double>& b);
This should aid with compile times? Would this affect the possibility the possibility of the functions being inlined? Are the answers to either of those questions generally compiler specific?
An added benefit is that it does verify that the function compiles, even if i haven't used it yet.
Also I could do this:
//in .h
template<typename T>
Vector3<T> foo(const Vector4<T>& a,
const Quaternion<T>& b);
//in .cpp
template<typename T>
Vector3<T> foo(const Vector4<T>& a,
const Quaternion<T>& b)
{ do something... }
template Vector3<float> foo<float>(const Vector4<float>& a,
const Quaternion<float>& b);
template Vector3<double> foo<double>(const Vector4<double>& a,
const Quaternion<double>& b);
Same questions for that method:
This should aid with compile times? Would this affect the possibility the possibility of the functions being inlined? Are the answers to either of those questions generally compiler specific?
I expect that the possibility of inlining would definitely be affected, considering the definition is not in the header.
It is nice that it manages to separate the declaration and definition for templated functions (for specific template arguments), without resorting to doing something like using a .inl included at the bottom of the .h file. This also hides the implementation from the user of the library which is beneficial (but not strictly necessary yet), while still being able to use templates so I don't have to implement a function N times.
Is there any way of allowing inlining by adjusting the method?
I have found it difficult just googling for an answer to these questions, and the standards specification is hard to comprehend on these subjects (for me at least).
BTW, this is expected to compile with VS2010, VS2012, and GCC 4.7.
Any assistance would be appreciated.
Thanks