#include #include #include #include template class VecImpl { public: using type = T; static constexpr std::size_t size_ = sizeof... (I); template && ...)>> constexpr VecImpl (Args&&... args) : data {{ std::forward (args)... }} { } constexpr VecImpl (const VecImpl&) = default; constexpr VecImpl (VecImpl&&) = default; VecImpl& operator = (const VecImpl&) = default; VecImpl& operator = (VecImpl&&) = default; static constexpr std::size_t size () { return size_; } const T& operator [] (std::size_t i) const { return data [i]; } T& operator [] (std::size_t i) { return data [i]; } std::array data; }; namespace Helper { template struct GetVecImpl; template struct GetVecImpl> { using type = VecImpl; }; } template using Vec = typename Helper::GetVecImpl>::type; template constexpr VecImpl vec_cast (const VecImpl& v) { return { static_cast (v.data [I]) ... }; } // Operatoren template auto operator +(const VecImpl& a, const VecImpl& b) -> VecImpl { return { (a.data [I] + b.data [I])... }; } template auto operator -(const VecImpl& a, const VecImpl& b) -> VecImpl { return { (a.data [I] - b.data [I])... }; } template auto operator *(const VecImpl& a, const VecImpl& b) -> VecImpl { return { (a.data [I] * b.data [I])... }; } template auto operator /(const VecImpl& a, const VecImpl& b) -> VecImpl { return { (a.data [I] / b.data [I])... }; } int main () { Vec a { 0.f, 1.f, 2.f }, b { 3.f, 4.f, 5.f }; Vec c { a + b }; Vec d { vec_cast (a) }; }