1
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) ;

所以这是我的问题,为什么我的转换运算符不起作用?是否有其他适合这个数学向量类的转换形式?

4

1 回答 1

3

问题是您的_Prd(谓词?)模板参数。转换运算符定义为

template<typename U> operator Vec<U,cn,_Prd> () const ;

这意味着元素类型U可以与T要转换的向量的元素类型不同,但是谓词类型必须匹配。在您的代码中,您使用的是默认谓词std::equal_to<T>,这对于您的两种类型是不同的,即您正在尝试转换

Vec<double, 2, std::equal_to<double>>

Vec<int, 2, std::equal_to<int>>.

这是您的编译器错误的来源。如果您想允许这种类型的转换,您需要向转换函数添加另一个模板参数:

template<typename U, typename Prd2> operator Vec<U,cn,Prd2> () const ;
于 2012-11-14T00:34:15.847 回答