Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template member variable specialization

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?

like image 805
bricklore Avatar asked Jan 30 '16 19:01

bricklore


People also ask

What is meant by template specialization?

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.

What does template <> mean in C++?

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.

How do you declare a template variable in C++?

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.

What is static members and variables of a 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> .


1 Answers

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

like image 146
Chris Beck Avatar answered Oct 20 '22 18:10

Chris Beck