前回、配列版の事を忘れていたので追加。
#pragma once ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// // プライマリテンプレート template<typename T> struct GETTER; ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// // 特殊化用の構造体//小文字 x,y,z用特殊化用の構造体 template<typename T> struct access_xyz { static inline double& X(T& v) { return v.x; } static inline double& Y(T& v) { return v.y; } static inline double& Z(T& v) { return v.z; } static inline const double& X(const T& v) { return v.x; } static inline const double& Y(const T& v) { return v.y; } static inline const double& Z(const T& v) { return v.z; } }; //大文字 X,Y,Z用特殊化用の構造体 template<typename T> struct access_XYZ { static inline double& X(T& v) { return v.X; } static inline double& Y(T& v) { return v.Y; } static inline double& Z(T& v) { return v.Z; } static inline const double& X(const T& v) { return v.X; } static inline const double& Y(const T& v) { return v.Y; } static inline const double& Z(const T& v) { return v.Z; } }; //配列用特殊化用の構造体 template<typename T> struct access_ARRAY{ static inline double& X(T& v) { return v[0]; } static inline double& Y(T& v) { return v[1]; } static inline double& Z(T& v) { return v[2]; } static inline const double& X(const T& v) { return v[0]; } static inline const double& Y(const T& v) { return v[1]; } static inline const double& Z(const T& v) { return v[2]; } };////////////////////////////////////////////////////// ////////////////////////////////////////////////////// // データ型(サンプル)
// 型1 struct vec_t { double x, y, z; }; // 型2 struct VEC_t { double X, Y, Z; };
////////////////////////////////////////////////////// ////////////////////////////////////////////////////// //特殊化1(デフォルトの型) template<> struct GETTER<vec_t> :public access_xyz<vec_t> {}; template<> struct GETTER<VEC_t> :public access_XYZ<VEC_t> {}; ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// // 特殊化2(ポインタ版) template<typename T> struct GETTER<T*> : public access_ARRAY<T*> {}; template<class T, std::size_t N> struct GETTER<T[N]> : public access_ARRAY<T[N]> {}; template<typename T, std::size_t N> struct GETTER<std::array<T, N> > : public access_ARRAY< std::array<T, N> > {};////////////////////////////////////////////////////// ////////////////////////////////////////////////////// // 関数本体 template< typename T, class G = GETTER<T> > double length(const T & v) { return sqrt( G::X(v) * G::X(v) + G::Y(v) * G::Y(v) + G::Z(v) * G::Z(v) ); } template< typename T, class G = GETTER<T> > void normalize(T & v) { double L = length(v); G::X(v) = G::X(v) / L; G::Y(v) = G::Y(v) / L; G::Z(v) = G::Z(v) / L; }
#include <iostream> #include <array> #include "len.hpp" ////エントリポイント int main() { double L; vec_t vv={ 1,1,1 }; L = length(vv); std::cout << L << std::endl; double xyz[3] = { 1,1,1 }; L = length(xyz); std::cout << L << std::endl; double* ptr = new double[3]{ 1,1,1 }; L = length(ptr); std::cout << L << std::endl; std::array<double, 3> ary = { 1,1,1 }; L = length(ary); std::cout << L << std::endl; int i; std::cin >> i; }