Ciao a tutti. Sto cercando di creare una classe che rappresenta dei vettori matematici.
Volevo chiedere agli esperti se utilizzo la move semantics in modo corretto e in caso contrario dove sbaglio e perché. Inoltre ottengo i warning seguenti per gli operatori friend della classe e non riesco proprio a capire perché.
Questo é il mio codice:codice:In file included from testVector.cc:1:0: Vector.h:50:51: warning: friend declaration ‘Vector<T> operator*(T, const Vector<T>&)’ declares a non-template function [-Wnon-template-friend] Vector.h:50:51: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) Vector.h:51:51: warning: friend declaration ‘Vector<T> operator*(const Vector<T>&, T)’ declares a non-template function [-Wnon-template-friend] Vector.h:52:68: warning: friend declaration ‘std::ostream& operator<<(std::ostream&, const Vector<T>&)’ declares a non-template function [-Wnon-template-friend] g++gcc-4.6.x testVector.o -o testVector
Grazie,codice:#ifndef VECTOR_H #define VECTOR_H #include <vector> // std::vector #include <initializer_list> // std::initializer_list #include <iostream> // std::ostream #include <string> // std::string #include <stdexcept> // std::range_error #include <algorithm> // std::copy // std::equal #include <iterator> // std::ostream_iterator #include <utility> // std::move template<typename T = double> class Vector { public: // --- CONSTRUCTORS --- Vector(size_t); Vector(T, T, T); Vector(const std::vector<T> &); Vector(const std::initializer_list<T>&); Vector(const Vector<T>&); Vector(Vector<T>&&); // --- DESTRUCTOR --- virtual ~Vector(); // --- INNER OPERATORS --- Vector<T>& operator=(const Vector<T>&); Vector<T>& operator=(const Vector<T>&&); bool operator==(const Vector<T>&) const; bool operator!=(const Vector<T>&) const; Vector<T>& operator+=(const Vector<T>&); Vector<T>& operator-=(const Vector<T>&); Vector<T> operator+(const Vector<T>&) const; Vector<T> operator-(const Vector<T>&) const; Vector<T> operator-() const; T operator*(const Vector<T>&) const; Vector<T> operator^(const Vector<T>&) const; T operator[](size_t) const; friend Vector<T> operator*(T, const Vector<T>&); friend Vector<T> operator*(const Vector<T>&, T); friend std::ostream& operator<<(std::ostream&, const Vector<T>&); // --- METHODS --- size_t size() const; double norm() const; protected: // --- ATTRIBUTES --- std::vector<T> v; // --- METHODS --- void range_except(const Vector<T>&, const std::string&) const; }; #endif // *** PUBLIC *** // --- CONSTRUCTORS --- // Empty vector template<typename T> Vector<T>::Vector(size_t size) : v(size, 0) {} // 3D vector template<typename T> Vector<T>::Vector(T x, T y, T z) : v({x, y, z}) {} template<typename T> Vector<T>::Vector(const std::vector<T> & V) : v(V) {} template<typename T> Vector<T>::Vector(const std::initializer_list<T>& V) : v(V) {} template<typename T> Vector<T>::Vector(const Vector<T>& V) : v(V) {} template<typename T> Vector<T>::Vector(Vector<T>&& V) : v(std::move(V)) {} // ---DESTRUCTOR --- template<typename T> Vector<T>::~Vector() {} // --- INNER OPERATORS --- template<typename T> Vector<T>& Vector<T>::operator=(const Vector<T>& V) { if(&V != this) { v = V; } return *this; } template<typename T> Vector<T>& Vector<T>::operator=(const Vector<T>&& V) { if(&V != this) { v = std::move(V); } return *this; } template<typename T> bool Vector<T>::operator==(const Vector<T>& V) const { if(v.size() == V.size()) { return equal(v.cbegin(), v.cend(), V.begin()); } return false; } template<typename T> bool Vector<T>::operator!=(const Vector<T>& V) const { return !( (*this) == V); } template<typename T> Vector<T>& Vector<T>::operator+=(const Vector<T>& V) { range_except(V, ""); for(int i(0); i < v.size(); i++) { v[i] += V.v[i]; } return *this; } template<typename T> Vector<T>& Vector<T>::operator-=(const Vector<T>& V) { range_except(V, ""); for(int i(0); i < v.size(); i++) { v[i] -= V.v[i]; } return *this; } template<typename T> Vector<T> Vector<T>::operator+(const Vector<T>& V) const { range_except(V, ""); Vector<T> r(*this); for(int i(0); i < v.size(); i++) { r.v[i] += V.v[i]; } return std::move(r); } template<typename T> Vector<T> Vector<T>::operator-(const Vector<T>& V) const { range_except(V, ""); Vector<T> r(*this); for(auto i : v) { r.v[i] -= V.v[i]; } return std::move(r); } template<typename T> Vector<T> Vector<T>::operator-() const { Vector<T> r(*this); for (size_t i(0); i < v.size(); i++) { r.v[i] = (-1) * r.v[i]; } return std::move(r); } template<typename T> T Vector<T>::operator*(const Vector<T>& V) const { range_except(V, ""); T r(0); for (size_t i(0); i < v.size(); i++) { r += v[i] * V.v[i]; } return r; } template<typename T> Vector<T> Vector<T>::operator^(const Vector<T>& V) const { range_except(V, ""); if (v.size() != 3) { throw std::range_error("Cross product works only for 3D vectors"); } Vector<T> r(v[1] * V.v[2] - v[2] * V.v[1], v[2] * V.v[0] - v[0] * V.v[2], v[0] * V.v[1] - v[1] * V.v[0]); return std::move(r); } template<typename T> T Vector<T>::operator[](size_t i) const { return v[i]; } template<typename T> Vector<T> operator*(T x, const Vector<T>& V) { Vector<T> r(V); for (size_t i(0); i < r.v.size(); i++) { r.v[i] *= x; } return std::move(r); } template<typename T> Vector<T> operator*(const Vector<T>& V, T x) { Vector<T> r(V); for (size_t i(0); i < r.v.size(); i++) { r.v[i] *= x; } return std::move(r); } template<typename T> std::ostream& operator<<(std::ostream& out, const Vector<T>& V) { std::copy(V.v.cbegin(), V.v.cend(), std::ostream_iterator<T>(out, " ")); return out; } // --- METHODS --- template<typename T> size_t Vector<T>::size() const { return v.size(); } template<typename T> double Vector<T>::norm() const { return std::sqrt((*this) * (*this)); } // *** PRIVATE *** // --- METHODS --- template<typename T> void Vector<T>::range_except(const Vector<T>& V, const std::string& s) const { if(v.size() != V.size()) { throw std::range_error(s); } }
R.

Rispondi quotando
