Одно решение, которое приходит на ум, - это частично специализированные шаблоны, которые опубликовал Мартин Йорк, но с изюминкой.
Я бы порекомендовал специальную структуру content_type для предоставления типа макета, например:
// content for non float types
template<typename T>
struct content_type {
typedef typename T member_type;
member_type x,y,z;
member_type& X { return x; }
// ...
// if access to optional members is needed, better use CT_ASSERT or similar
member_type& Pad { char assert_error_no_pad_here[0]; }
};
// content for float types
struct content_type<float> {
typedef typename float member_type;
member_type x, y, z, pad;
member_type& X { return x; }
// ...
member_type& Pad { return pad; }
};
template<typename T>
class Vector3 {
typedef typename content_type<T> layout_type;
typedef typename content_type<T>::member_type member_type;
layout_type _content;
public:
member_type& X { return _content.X(); }
memmber_type& Pad { return _content.Pad(); }
};
// or maybe, if memory layout is not important, just inherit (watch for virtual members)
template<typename T>
class Vector3 : public content_type<T> {
typedef typename content_type<T> layout_type;
typedef typename content_type<T>::member_type member_type;
};
Преимущество в том, что вам нужно написать Vector3 со всей его логикой только один раз.
Для корректной работы необходим компилятор сравнительно недавнего времени (MSVC> 7, gcc> 3)