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é.
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
Questo é il mio codice:
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);
	}
}
Grazie,
R.