template<typename T, int cn, typename _Prd = equal_to<T> > //watch out this <T>, when convert it to other typename, _Prd changes too.
struct Vec
{
//output overloading
// c++ gotcha, must forward declare this, and with <> .
friend std::ostream& operator<< <>(std::ostream& output, const Vec<T,cn,_Prd>& out);
friend const Vec<T,cn,_Prd> operator+ <>(const Vec<T,cn,_Prd>& lhs, const Vec<T,cn,_Prd>& rhs) ;
friend const Vec<T,cn,_Prd> operator+ <>(const T& lhs, const Vec<T,cn,_Prd>& rhs) ;
friend const Vec<T,cn,_Prd> operator+ <>(const Vec<T,cn,_Prd>& lhs, const T& rhs) ;
friend const Vec<T,cn,_Prd> operator- <>(const Vec<T,cn,_Prd>& lhs, const Vec<T,cn,_Prd>& rhs) ;
friend const Vec<T,cn,_Prd> operator- <>(const T& lhs, const Vec<T,cn,_Prd>& rhs) ;
friend const Vec<T,cn,_Prd> operator- <>(const Vec<T,cn,_Prd>& lhs, const T& rhs) ;
friend const Vec<T,cn,_Prd> operator* <>(const T& lhs, const Vec<T,cn,_Prd>& rhs) ;
friend const Vec<T,cn,_Prd> operator* <>(const Vec<T,cn,_Prd>& lhs, const T& rhs) ;
protected:
T data[cn] ;
_Prd comp ;
public:
typedef T value_type ;
Vec() ;
Vec(T v0, T v1) ;
Vec(T v0, T v1, T v2) ;
Vec(T v0, T v1, T v2, T v3) ;
explicit Vec(const T* values) ;
explicit Vec(const T& value) ;
//copy constructor, incase delete twice
Vec(const Vec<T, cn, _Prd>& v) ;
//Get Magnituede
T magnituede() const ;
//Dot product
T dot(const Vec<T, cn, _Prd>& b) const ;
//cross product of two 3D vectors, other dimension raises exception
Vec<T, cn, _Prd>& cross(const Vec<T, cn, _Prd>& v) const ;
//product of all elements
T product() ;
//scale vector to 1
Vec<T, cn, _Prd>& normalize() ;
Vec<T,cn,_Prd> normalize(const Vec<T,cn,_Prd>& rhs) ;
//change length of the vector
Vec<T, cn, _Prd>& scale(const T &length);
Vec<T, cn, _Prd> scale(const Vec<T,cn,_Prd> &rhs,const T &length) ;
//project
Vec<T, cn, _Prd> projectTo (const Vec<T,cn,_Prd>& rhs) ;
//Operators
//element access
const T& operator[](const int& i) const ;
T& operator[](const int& i) ;
//return element number
T GetSize() ;
//comparison
bool operator==(const Vec<T,cn,_Prd>& rhs) const ;
bool operator!=(const Vec<T,cn,_Prd>& rhs) const ;
//function call operators
Vec<T,cn,_Prd>& operator() (const T* rhs) ;
Vec<T,cn,_Prd>& operator() (const Vec<T,cn,_Prd>& rhs );
//assignment
Vec<T,cn,_Prd>& operator=(const Vec<T,cn,_Prd>& rhs) ; //care, here is no copy
Vec<T,cn,_Prd>& operator=(const T rhs[cn]) ;
Vec<T,cn,_Prd> operator=(const T& rhs) ; //assignment constructor
Vec<T,cn,_Prd> operator-() const;
//math
Vec<T,cn,_Prd>& operator+=(const Vec<T,cn,_Prd>& rhs) ;
Vec<T,cn,_Prd>& operator+=(const T& rhs) ;
Vec<T,cn,_Prd>& operator-=(const Vec<T,cn,_Prd>& rhs) ;
Vec<T,cn,_Prd>& operator-=(const T& rhs) ;
Vec<T,cn,_Prd>& operator*=(const T& rhs) ;
static Vec<T, cn, _Prd> abs(const Vec<T,cn,_Prd>& rhs) ;
static void swap(Vec<T,cn,_Prd>& a,Vec<T,cn,_Prd>& b) ;
//conversion
template<typename U> operator Vec<U,cn,_Prd> () const ;
};
この変換演算子は私を夢中にさせます。
template<typename U> operator Vec<U,cn,_Prd> () const ;
実装は次のとおりです。
//conversion
template<typename T, int cn, typename _Prd>
template<typename U>
Vec<T,cn,_Prd>::operator Vec<U,cn,_Prd> () const
{
U temp[cn] ;
for (int i = 0 ; i < cn ; ++i)
temp[i] = static_cast<U>(this->data[i]) ;
Vec<U,cn,_Prd> v(temp) ;
return v ;
};
inline void foo (Vec<int,2> test)
{
std::cout <<"works" << std::endl ;
}
そして、呼び出しは次のとおりです。
Vec<double,2> vec25(234.5,2352.5) ;
foo(vec25) ;
Vec<int,2> vec26 = Vec<int,2>(vec25) ;
エラーは次のとおりです。
tests/newsimpletest1.cpp:74: error: conversion from ‘Vec<double, 2, std::equal_to<double> >’ to non-scalar type ‘Vec<int, 2, std::equal_to<int> >’ requested
tests/newsimpletest1.cpp:75: error: no matching function for call to ‘Vec<int, 2, std::equal_to<int> >::Vec(Vec<double, 2, std::equal_to<double> >&)’
./Vec.hpp:186: note: candidates are: Vec<T, cn, _Prd>::Vec(const Vec<T, cn, _Prd>&) [with T = int, int cn = 2, _Prd = std::equal_to<int>]
./Vec.hpp:180: note: Vec<T, cn, _Prd>::Vec(const T&) [with T = int, int cn = 2, _Prd = std::equal_to<int>]
./Vec.hpp:173: note: Vec<T, cn, _Prd>::Vec(const T*) [with T = int, int cn = 2, _Prd = std::equal_to<int>]
./Vec.hpp:166: note: Vec<T, cn, _Prd>::Vec(T, T, T, T) [with T = int, int cn = 2, _Prd = std::equal_to<int>]
./Vec.hpp:159: note: Vec<T, cn, _Prd>::Vec(T, T, T) [with T = int, int cn = 2, _Prd = std::equal_to<int>]
./Vec.hpp:149: note: Vec<T, cn, _Prd>::Vec(T, T) [with T = int, int cn = 2, _Prd = std::equal_to<int>]
./Vec.hpp:145: note: Vec<T, cn, _Prd>::Vec() [with T = int, int cn = 2, _Prd = std::equal_to<int>]
ただし、別のプロジェクトで試してみましたが、動作します。
template <typename T>
class varmani
{
T var ;
public:
varmani (T var_){
var = var_ ;
}
T increase() {
return ++var ;
}
template<typename U> operator varmani<U> () const;
};
void foo (varmani<int> test)
{
std::cout << "works" << std::endl ;
}
template <typename T>
template <typename U>
varmani<T>::operator varmani<U> () const
{
U temp = static_cast<U>(this->var) ;
varmani<U> v(temp) ;
return v ;
}
//all works
varmani<double> test3(10.25) ;
varmani<int> test4 = varmani<int>(test3) ;
foo(test3) ;
ここに私の質問があります。変換演算子が機能しないのはなぜですか? この数学ベクトル クラスに適した他の変換形式はありますか?