2016-01-30 3 views
4

У меня есть template class с множеством функций и хочу только выделить некоторые из них, а также добавить переменную-член.template member переменная специализация

Возможно ли это без необходимости переопределения всех функций для специализированного класса?


Что у меня есть:

template<class T> class Vector3 
{ 
    union { 
     T data[3]; 
     struct { T x, y, z; }; 
    }; 

    //a lot of functions 

    T Length() { ... }; 
}; 

Что я хочу сделать:

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> 
    }; 
}; 

В 95% всех функций оставаться точно таким же, я определенно не хочу для их повторной реализации для каждой отдельной специализации. Как я могу это достичь?

ответ

1

Одна вещь, которую вы могли бы сделать, это сделать шаблон помощник, который генерирует тип структуры, с-союз, который является «ядром» вашего типа:

template <typename T> 
struct Vector3_core { 
    union { 
    T data[3]; 
    struct { T x, y, z; }; 
    }; 

    T length() { ... } 
}; 

и специализироваться его float по желанию:

template <> 
struct Vector3_core<float> { 
    union { 
    float data[3]; 
    struct { float x, y, z; }; 
    __m128 xmm; 
    }; 

    float Length() { ... } 
}; 

Тогда вы могли бы написать основной класс с помощью простого наследования, как:

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... 
}; 

Обратите внимание, что виртуальная отправка здесь отсутствует. Кроме того, вам не обязательно делать наследование общедоступным, вы можете сделать его приватным и переслать функцию Length публично.

Вы также можете пойти дальше и использовать полномасштабный CRTP, если это было бы полезно.

Вот пример кода на Coliru, показывающий, что идея работает на стандарте C++ 11, по крайней мере.

http://coliru.stacked-crooked.com/a/ef10d0c574a5a040

+0

Очень interresting подход, но я буду прав, полагая, что я не буду иметь возможность прямого доступа к членам профсоюза, как в моем первом примере? Поэтому мне придется использовать impl.x и impl.y ...? – bricklore

+0

Отредактировано для обсуждения вашей озабоченности по поводу 'impl.x, impl.y' и т. Д. –

+0

Спасибо - это именно то, что я искал! – bricklore

Смежные вопросы