diff --git a/dlib/matrix/matrix.h b/dlib/matrix/matrix.h
index 45633b3f382fc48470f67c0a105298f4a0678d7f..850fb015688c1f565861dd2cd1feaa97642cc871 100644
--- a/dlib/matrix/matrix.h
+++ b/dlib/matrix/matrix.h
@@ -146,14 +146,14 @@ namespace dlib
         long nc (
         ) const { return get_nc_helper<exp_type,NC>::get(ref()); }
 
-        template <typename U, long iNR, long iNC, typename mm, typename l >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const { return ref().aliases(item); }
 
-        template <typename U, long iNR, long iNC , typename mm, typename l>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const { return ref().destructively_aliases(item); }
 
         inline const exp_type& ref (
@@ -359,14 +359,14 @@ namespace dlib
         long nc (
         ) const { return rhs.nc(); }
 
-        template <typename U, long iNR, long iNC, typename mm, typename l >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const { return lhs.aliases(item) || rhs.aliases(item); }
 
-        template <typename U, long iNR, long iNC , typename mm, typename l>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const { return aliases(item); }
 
         LHS_ref_type lhs;
@@ -508,14 +508,14 @@ namespace dlib
         inline const type operator() ( long i ) const 
         { return matrix_exp<matrix_add_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC , typename mm, typename l>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const { return lhs.aliases(item) || rhs.aliases(item); }
 
-        template <typename U, long iNR, long iNC, typename mm, typename l >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const { return lhs.destructively_aliases(item) || rhs.destructively_aliases(item); }
 
         long nr (
@@ -614,14 +614,14 @@ namespace dlib
         inline const type operator() ( long i ) const 
         { return matrix_exp<matrix_subtract_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename mm, typename l >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC, mm,l>& item
+            const matrix_exp<U>& item
         ) const { return lhs.aliases(item) || rhs.aliases(item); }
 
-        template <typename U, long iNR, long iNC , typename mm, typename l>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const { return lhs.destructively_aliases(item) || rhs.destructively_aliases(item); }
 
         long nr (
@@ -701,14 +701,14 @@ namespace dlib
         inline const type operator() ( long i ) const 
         { return matrix_exp<matrix_div_scal_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename mm , typename l>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const { return m.aliases(item); }
 
-        template <typename U, long iNR, long iNC, typename mm, typename l >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const { return m.destructively_aliases(item); }
 
         long nr (
@@ -791,14 +791,14 @@ namespace dlib
         inline const type operator() ( long i ) const 
         { return matrix_exp<matrix_mul_scal_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC , typename mm, typename l>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const { return m.aliases(item); }
 
-        template <typename U, long iNR, long iNC, typename mm, typename l >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const { return m.destructively_aliases(item); }
 
         long nr (
@@ -1488,20 +1488,20 @@ namespace dlib
             data.swap(item.data);
         }
 
-        template <typename U, long iNR, long iNC, typename mm, typename l >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,mm,l>& 
-        ) const  { return false; }
-
-        template <typename U, long iNR, long iNC, typename mm, typename l>
-        bool destructively_aliases (
-            const matrix<U,iNR,iNC,mm,l>& 
+            const matrix_exp<U>& item
         ) const { return false; }
 
         bool aliases (
-            const matrix& item
+            const matrix_exp<matrix<T,num_rows,num_cols, mem_manager,layout> >& item
         ) const { return (this == &item); }
 
+        template <typename U>
+        bool destructively_aliases (
+            const matrix_exp<U>& 
+        ) const { return false; }
+
     private:
         struct literal_assign_helper
         {
@@ -1752,14 +1752,14 @@ namespace dlib
         const type operator() ( long i ) const 
         { return ref_(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return ref_.aliases(item); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return ref_.destructively_aliases(item); }
 
         long nr (
diff --git a/dlib/matrix/matrix_abstract.h b/dlib/matrix/matrix_abstract.h
index 16043137fbb8209c0711b3a633f8fa0714e9f7c3..c7df87393eab749e2525a9a1c0055f886d2b2c61 100644
--- a/dlib/matrix/matrix_abstract.h
+++ b/dlib/matrix/matrix_abstract.h
@@ -123,22 +123,23 @@ namespace dlib
                 - returns nr()*nc()
         !*/
 
-        template <typename U, long iNR, long iNC , typename mm, typename l>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const;
         /*!
             ensures
-                - if (this matrix expression contains/aliases the given matrix or contains
-                  any subexpressions that contain/alias the given matrix) then
+                - if (A change to the state of item could cause a change to the state of *this
+                      matrix_exp object.  ) then
                     - returns true
+                    - This happens when this matrix_exp contains item in some way. 
                 - else
                     - returns false
         !*/
 
-        template <typename U, long iNR, long iNC, typename mm, typename l>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,mm,l>& item
+            const matrix_exp<U>& item
         ) const; 
         /*!
             ensures
@@ -148,7 +149,7 @@ namespace dlib
                           (i.e. if this expression has different dimensions than item then
                           we have destructive aliasing)
 
-                    - returns true if the following expression would evaluate incorrectly:
+                    - returns true if the following assignment would evaluate incorrectly:
                       for (long r = 0; r < nr(); ++r)
                         for (long c = 0; c < nc(); ++c)
                           item(r,c) = (*this)(r,c)
diff --git a/dlib/matrix/matrix_expressions.h b/dlib/matrix/matrix_expressions.h
index b9271e45c2e70e1cfed078529d20ab47bcd2bcff..4b6007da9d6b9cee140cf4dddf501fb8b841cf97 100644
--- a/dlib/matrix/matrix_expressions.h
+++ b/dlib/matrix/matrix_expressions.h
@@ -102,34 +102,34 @@ namespace dlib
 
     struct has_destructive_aliasing
     {
-        template <typename M, typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename M, typename U>
         static bool destructively_aliases (
             const M& m,
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) { return m.aliases(item); }
 
-        template <typename M1, typename M2, typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename M1, typename M2, typename U>
         static bool destructively_aliases (
             const M1& m1,
             const M2& m2,
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) { return m1.aliases(item) || m2.aliases(item) ; }
 
-        template <typename M1, typename M2, typename M3, typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename M1, typename M2, typename M3, typename U>
         static bool destructively_aliases (
             const M1& m1,
             const M2& m2,
             const M3& m3,
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item); }
 
-        template <typename M1, typename M2, typename M3, typename M4, typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename M1, typename M2, typename M3, typename M4, typename U>
         static bool destructively_aliases (
             const M1& m1,
             const M2& m2,
             const M3& m3,
             const M4& m4,
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item) || m4.aliases(item); }
     };
 
@@ -137,34 +137,34 @@ namespace dlib
 
     struct has_nondestructive_aliasing
     {
-        template <typename M, typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename M, typename U>
         static bool destructively_aliases (
             const M& m,
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) { return m.destructively_aliases(item); }
 
-        template <typename M1, typename M2, typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename M1, typename M2, typename U>
         static bool destructively_aliases (
             const M1& m1,
             const M2& m2,
-            const matrix<U,iNR,iNC, MM, L>& item
+            const matrix_exp<U>& item
         ) { return m1.destructively_aliases(item) || m2.destructively_aliases(item) ; }
 
-        template <typename M1, typename M2, typename M3, typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename M1, typename M2, typename M3, typename U>
         static bool destructively_aliases (
             const M1& m1,
             const M2& m2,
             const M3& m3,
-            const matrix<U,iNR,iNC, MM, L>& item
+            const matrix_exp<U>& item
         ) { return m1.destructively_aliases(item) || m2.destructively_aliases(item) || m3.destructively_aliases(item) ; }
 
-        template <typename M1, typename M2, typename M3, typename M4, typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename M1, typename M2, typename M3, typename M4, typename U>
         static bool destructively_aliases (
             const M1& m1,
             const M2& m2,
             const M3& m3,
             const M4& m4,
-            const matrix<U,iNR,iNC, MM, L>& item
+            const matrix<U>& item
         ) { return m1.destructively_aliases(item) || 
                    m2.destructively_aliases(item) || 
                    m3.destructively_aliases(item) || 
@@ -261,14 +261,14 @@ namespace dlib
         const typename OP::type operator() ( long i ) const 
         { return matrix_exp<matrix_unary_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return m.aliases(item); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return OP::destructively_aliases(m,item); }
 
         long nr (
@@ -343,14 +343,14 @@ namespace dlib
         const typename OP::type operator() ( long i ) const 
         { return matrix_exp<matrix_scalar_binary_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return m.aliases(item); }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return OP::destructively_aliases(m,item); }
 
         long nr (
@@ -428,14 +428,14 @@ namespace dlib
         const typename OP::type operator() ( long i ) const 
         { return matrix_exp<matrix_scalar_ternary_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return m.aliases(item); }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return OP::destructively_aliases(m,item); }
 
         long nr (
@@ -510,14 +510,14 @@ namespace dlib
         const typename OP::type operator() ( long i ) const 
         { return matrix_exp<matrix_binary_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return m1.aliases(item) || m2.aliases(item); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return OP::destructively_aliases(m1,m2,item); }
 
         long nr (
@@ -595,14 +595,14 @@ namespace dlib
         const typename OP::type operator() ( long i ) const 
         { return matrix_exp<matrix_ternary_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return OP::destructively_aliases(m1,m2,m3,item); }
 
         long nr (
@@ -684,14 +684,14 @@ namespace dlib
         const typename OP::type operator() ( long i ) const 
         { return matrix_exp<matrix_fourary_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return m1.aliases(item) || m2.aliases(item) || m3.aliases(item) || m4.aliases(item); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return OP::destructively_aliases(m1,m2,m3,m4,item); }
 
         long nr (
@@ -763,14 +763,14 @@ namespace dlib
         const typename OP::type operator() ( long i ) const 
         { return matrix_exp<dynamic_matrix_scalar_unary_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
         long nr (
@@ -837,14 +837,14 @@ namespace dlib
         const typename OP::type operator() ( long i ) const 
         { return matrix_exp<matrix_scalar_unary_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
         long nr (
@@ -899,14 +899,14 @@ namespace dlib
         const typename OP::type operator() ( long i ) const 
         { return matrix_exp<matrix_zeroary_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return false; }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return false; }
 
         long nr (
@@ -981,14 +981,14 @@ namespace dlib
         const typename M::type operator() ( long i ) const 
         { return matrix_exp<matrix_sub_range_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return m.aliases(item) || rows.aliases(item) || cols.aliases(item); }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return m.aliases(item) || rows.aliases(item) || cols.aliases(item); }
 
         long nr (
@@ -1059,14 +1059,14 @@ namespace dlib
         const typename M::value_type& operator() ( long i ) const 
         { return m[i]; }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
         long nr (
@@ -1134,14 +1134,14 @@ namespace dlib
         const typename M::type& operator() ( long i ) const 
         { return m[i]; }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return false; }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return false; }
 
         long nr (
@@ -1209,14 +1209,14 @@ namespace dlib
         const typename M::type operator() ( long i ) const 
         { return matrix_exp<matrix_array2d_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
         long nr (
@@ -1291,14 +1291,14 @@ namespace dlib
         const typename M::type operator() ( long i ) const 
         { return matrix_exp<matrix_sub_exp>::operator()(i); }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return m.aliases(item); }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return m.aliases(item); }
 
         long nr (
@@ -1396,14 +1396,14 @@ namespace dlib
             long c
         ) const { return start + c*inc;  }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
         long nr (
@@ -1474,14 +1474,14 @@ namespace dlib
             long c
         ) const { return std::pow(10,start + c*inc);  }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& 
+            const matrix_exp<U>& 
         ) const { return false; }
 
         long nr (
@@ -1537,14 +1537,14 @@ namespace dlib
             long c
         ) const { return start + c*inc;  }
 
-        template <typename U, long iNR, long iNC , typename MM, typename L>
+        template <typename U>
         bool aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return false; }
 
-        template <typename U, long iNR, long iNC, typename MM, typename L >
+        template <typename U>
         bool destructively_aliases (
-            const matrix<U,iNR,iNC,MM,L>& item
+            const matrix_exp<U>& item
         ) const { return false; }
 
         long nr (