Ok I have two classes: matrix_rowand matrix_column, which (as their names say) represent rows and columns of matrices. I do this to perform operations between matrix rows / columns ("Lines") in a simple way. Something like that m1.row(1) = m1.column(0) + m2.row(7).
Since the two types of strings are almost the same, except for the way to access the basic elements, I have a CRTP base class containing all the operations. Then the two classes superimposed above inherit from it and determine their own way of accessing the element through static sending:
template<typename T , std::size_t ROWS , std::size_t COLUMNS , typename DERIVED>
struct line
{
std::reference_wrapper<matrix<T,ROWS,COLUMNS>> ref;
std::size_t index;
...
};
template<typename T , std::size_t ROWS , std::size_t COLUMNS>
struct matrix_row : public line<T,ROWS,COLUMNS,matrix_row<T,ROWS,COLUMNS>>
{
const T& at( std::size_t index ) const { return this->matrix_ref.get()[this->index][index]; }
T& at( std::size_t index ) { return this->matrix_ref.get()[this->index][index]; }
using base_t::operator=;
};
template<typename T , std::size_t ROWS , std::size_t COLUMNS>
struct matrix_column : public line<T,ROWS,COLUMNS,matrix_column<T,ROWS,COLUMNS>>
{
const T& at( std::size_t index ) const { return this->matrix_ref.get()[index][this->index]; }
T& at( std::size_t index ) { return this->matrix_ref.get()[index][this->index]; }
using base_t::operator=;
};
, , . std::swap() , , (, ). swap() :
template<typename LHS_T , typename RHS_T ,
std::size_t LHS_Rs , std::size_t RHS_Rs ,
std::size_t LHS_Cs , std::size_t RHS_Cs ,
typename LHS_D , typename RHS_D
>
friend void swap( line<LHS_T,LHS_Rs,LHS_Cs,LHS_D>& lhs , line<RHS_T,RHS_Rs,RHS_Cs,RHS_D>& rhs )
{
assert( lhs.length == rhs.length );
for( std::size_t i = 0 ; i < lhs.length ; ++i )
std::swap( lhs[i] , rhs[i] );
}
(, ), .
:
, (at()). , , (Thats, , virtual ) ,
swap() no known conversion from [derived] to [base]&. ? , ?