можно сделать арифметические c выражения для векторных объектов? - PullRequest
0 голосов
/ 03 февраля 2020

Для 3-векторного класса

template <typename T>
class vec3 {

   template <typename U>
   friend std::ostream& operator<<(std::ostream& out, const vec3<U>& v);

   template <typename U>
   friend std::istream& operator>>(std::istream& in, vec3<U>& v);

   protected:
   std::vector<T> data;

   public:
   vec3 (                    ): data(3)
        {}; // default constructor

   vec3 ( T x,   T y,   T z  ): data(3)
        { data[0] = x; data[1] = y; data[2] = z; } // constructor from 3 scalars

   vec3 ( T* xyz             ): data(3)
        { std::copy (xyz, xyz+3, data.begin() ); } // constructor from pointer

   vec3 ( const vec3<T>& rhs ): data(3)
        { std::copy ( rhs.data.begin(), rhs.data.end(), data.begin() ); } // copy constructor

   vec3<T> operator=( vec3<T> rhs ) {
        std::copy( rhs.data.begin(), rhs.data.end(), data.begin() ); // assignment    
        return (*this);
   }

   // passing on the [] operator for accessing elements
   T& operator[] ( size_t offset)       
         { return data[offset]; } // write access
   const T& operator[] ( size_t offset) const 
         { return data[offset]; } // read  access

   // left += and + for elements and vectors
   template <typename U>
   const vec3<T>& operator+= ( const U& rhs )       
         { data[0]+=rhs;    data[1]+=rhs;    data[2]+=rhs;    return (*this); }
   template <typename U>
   const vec3<T>& operator+= ( const vec3<U>& rhs ) 
         { data[0]+=rhs[0]; data[1]+=rhs[1]; data[2]+=rhs[2]; return (*this); }
   template <typename U>
   const vec3<T> operator+   ( const U& rhs )       
         { vec3<T> out(*this); out += rhs; return out;                        }

   // left *= and * for elements and vectors
   template <typename U>
   const vec3<T>& operator*= ( const U& rhs )       
         { data[0]*=rhs;    data[1]*=rhs;    data[2]*=rhs;    return (*this); }
   template <typename U>
   const vec3<T>& operator*= ( const vec3<U>& rhs ) 
         { data[0]*=rhs[0]; data[1]*=rhs[1]; data[2]*=rhs[2]; return (*this); }
   template <typename U>
   const vec3<T> operator*   ( const U& rhs )       
         { vec3<T> out(*this); out *= rhs; return out;                        }

   // rest of the operators

}

template <typename U>
std::ostream& operator<<(std::ostream& out, const vec3<U>& v)
   { return out << '(' << v.data[0] << ',' << v.data[1] << ',' << v.data[2] <<')'; }

template <typename U>
std::istream& operator>>(std::istream& in , vec3<U> &v)
   { return in >> v.data[0] >> v.data[1] >> v.data[2]; }

Я попытался запустить этот бит кода

float v[3] = { 10, 20, 30 };

vec3<float> v1 (v);
std::cout << v1 << " \n";
vec3<float> v2 (v1);
std::cout << v2 << " \n";
vec3<float> v3 = v2;
std::cout << v3 << " \n \n";

v3+=1.;
std::cout << v3 << " \n";
v3=v1+v2*2;
std::cout << v3 << " \n";

, который возвращает

(10,20,30) 
(10,20,30) 
(10,20,30) 

(11,21,31) 
Segmentation fault

Так что я достаточно уверенный в конструкторе копирования, присваивании et c. но нельзя ли передать результат операции * в +? Возвращает const vec3<T> так что же здесь не так? Какая-то ладья ie ошибка, наверное, но я ее не вижу.

1 Ответ

0 голосов
/ 04 февраля 2020
v3=v1+v2*2;

эта строка делает рекурсивные вызовы функции

template <typename T, typename U>
inline vec3 <T> operator+ (U x, vec3 <T> y) {
    return y + x;
}

, она выдает ошибку сегментации после переполнения стека. если вы удалите эту функцию, функция-член const vec3<T> operator+ ( const U& rhs ) будет вызвана для операции, и она будет работать нормально.

вам следует добавить глобальную операторную функцию, которую вы определили в свой вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...