Я хочу написать общий (математический) векторный класс, который поддерживает swizzling, для этого я нашел две ссылки (CxxSwizzle и Performance Optimal Vector Swizzling in C++ ²). Мне нравится прямолинейный стиль реализации swizzling в качестве подкласса членов профсоюза в ², но я хочу узнать о вариантах вариационного шаблона, как это делается в CxxSwizzle.Реализация векторного вектора C++ Variadic
Вот небольшой отрывок, который я не знаю, как реализовать (шаблонный функция SQRT находится здесь, чтобы реализовать длину/величину для определенного пользователя типов):
#include <cmath>
#include <cstdint>
#include <type_traits>
template<class T>
using vec_sqrt_function = typename std::add_pointer<T(const T)>::type;
template<class VEC_TYPE, class T, vec_sqrt_function<T> SQRT_FN, std::int32_t... X>
struct vec_impl
{
template<class VEC_TYPE2, class T2, vec_sqrt_function<T2> SQRT_FN2, std::int32_t... X2>
VEC_TYPE& operator +=(const vec<VEC_TYPE2, T2, SQRT_FN2, ...X2>& RHS)
{
// ???
return *this;
}
};
struct vec2 : public vec_impl<vec2, float, std::sqrt, 0, 1>
{
union
{
float data[2];
vec_impl<vec2, float, std::sqrt, 0> x;
vec_impl<vec2, float, std::sqrt, 1> y;
vec_impl<vec2, float, std::sqrt, 0, 0> xx;
vec_impl<vec2, float, std::sqrt, 0, 1> xy;
vec_impl<vec2, float, std::sqrt, 1, 0> yx;
vec_impl<vec2, float, std::sqrt, 1, 1> yy;
};
};
Из того, что я понял из чтение нескольких учебных пособий заключается в том, что мне нужно специализировать vec_impl
с шаблоном формы template<..., std::int32_t X, std::int32_t... REST>
, но так как я использую тот же вариационный шаблон для оператора +=
, мне нужно специализировать оператор +=
таким же образом, в целом для реализации того же функция 4 раза?
Есть ли более простой способ реализовать это (я не совсем понял, как CxxSwizzle реализует арифметику через все шаблоны)?
Редактировать: Для дальнейшего уточнения, что я хочу знать, как синтаксический реализовать следующий через переменные число шаблонов вместо раздельных классов:
template<class VEC_TYPE, class T, std::int32_t X1>
struct vec1_swizzle
{
template<class VEC_TYPE2, class T2, std::int32_t Y1>
VEC_TYPE& operator += (const vec1_swizzle<VEC_TYPE2, T2, Y1>& RHS)
{
((T*)this)[X1] += ((T*)&RHS)[Y1];
return *this;
}
}
struct vec1f : public vec1_swizzle<vec1f, float, 0>
{
union
{
float data[1];
vec1_swizzle<vec1f, float, 0> x;
vec2_swizzle<vec2f, float, 0, 0> xx;
// same for 3 & 4
}
}
template<class VEC_TYPE, class T, std::int32_t X1, std::int32_t X2>
struct vec2_swizzle
{
template<class VEC_TYPE2, class T2, std::int32_t Y1, std::int32_t Y2>
VEC_TYPE& operator += (const vec1_swizzle<VEC_TYPE2, T2, Y1, Y2>& RHS)
{
((T*)this)[X1] += ((T*)&RHS)[Y1];
((T*)this)[X2] += ((T*)&RHS)[Y2];
return *this;
}
}
struct vec2f : public vec2_swizzle<vec2f, float, 0, 1>
{
union
{
float data[2];
vec1_swizzle<vec1f, float, 0> x;
vec1_swizzle<vec1f, float, 1> y;
vec2_swizzle<vec2f, float, 0, 0> xx;
vec2_swizzle<vec2f, float, 0, 1> xy;
vec2_swizzle<vec2f, float, 1, 0> yx;
vec2_swizzle<vec2f, float, 1, 1> yy;
// same for 3 & 4
}
}
Я хочу «generify» в vec#_swizzle
классе по шаблонам количество прошедших индексов.
Добавление двух векторов имеет смысл только если они одинаковой длины, нет? – AndyG
Это очень странный способ попытаться реализовать 'vec2'. Вы уверены, что понимаете, как работает профсоюз? Жесткая правда заключается в том, что многие из этого, похоже, слишком сложны для вашего уровня понимания языка на данном этапе. Начните с малого, с чтением о полиморфизме, а затем в векторах, а затем в стиле C++ 03. А затем вариативные шаблоны, статические утверждения, специализированные шаблоны, специализация частичного шаблона (особенно для функций-членов). И что такое союз. (boost :: variant или std :: variant также хорошо читаются). – AndyG
@ AndyG Я думаю, что вы неправильно поняли мой вопрос. Я знаю, как реализовать то, что я хочу, используя отдельные шаблонные классы. Я спрашивал, как реализовать его в одном классе, если это имеет смысл (это скорее вопрос синтаксиса, чем логический вопрос), я редактировал вопрос, надеюсь, быть более ясно о том, что я хочу знать. – prydain