I have a template class
with lots of functions and only want to specialize a few of them, while also adding a member variable.
Is that possible without the need to reimplement all the functions for the specialized class?
What I have:
template<class T> class Vector3
{
union {
T data[3];
struct { T x, y, z; };
};
//a lot of functions
T Length() { ... };
};
What I want to do:
template<> class Vector3<float>
{
union {
float data[3];
struct { float x, y, z; };
//new union member only for <float>!
__m128 xmm;
};
float Length() {
//special instructions for special case <float>
};
};
As 95% of all functions stay exactly the same, I definitely don't want to reimplement them for every single specialization. How can I achieve that?
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.
A template is a C++ programming feature that permits function and class operations with generic types, which allows functionality with different data types without rewriting entire code blocks for each type.
A variable template may be introduced by a template declaration at namespace scope, where variable-declaration declares a variable. When used at class scope, variable template declares a static data member template.
Static data members and templates (C++ only)The static declaration can be of template argument type or of any defined type. The statement template T K::x defines the static member of class K , while the statement in the main() function assigns a value to the data member for K <int> .
One thing you could do is make a helper template that generates a structure-with-union type that is the "core" of your type:
template <typename T>
struct Vector3_core {
union {
T data[3];
struct { T x, y, z; };
};
T length() { ... }
};
and specialize it for float
as desired:
template <>
struct Vector3_core<float> {
union {
float data[3];
struct { float x, y, z; };
__m128 xmm;
};
float Length() { ... }
};
Then you could write the main class using simple inheritance like:
template<class T> class Vector3 : public Vector3_core<T>
{
// Need to pull anonymous-struct members into this class' scope
using Vector3_core<T>::x;
using Vector3_core<T>::y;
using Vector3_core<T>::z;
// All your functions...
};
Note that there is no virtual-dispatch going on here. Also, you don't need to make the inheritance public necessarily, you could make it private and forward the Length
function publicly.
You could also go further and use full-blown CRTP if would be useful.
Here's a code sample on Coliru showing that the idea works at C++11 standard, at least.
http://coliru.stacked-crooked.com/a/ef10d0c574a5a040
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With