スポンサーリンク

色々な型に対応できる関数を作る(4)特殊化を短くする(配列込み)

前回、配列版の事を忘れていたので追加。

len.hpp

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

main.cpp

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

}

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: