いくつでも行列足し算できる奴も出来た. gcc-4.8.0で動作確認, 4.3.4ではコンパイル出来なかった.
元ネタ
http://itee.uq.edu.au/~conrad/misc/sanderson_templates_lecture_uqcomp7305.pdf
#include<iostream>
template< typename T1, typename T2 >
class Glue;
template< typename derived>
struct Base {
const derived & get_ref() const{
return static_cast<const derived&>(*this);
}
};
class Matrix : public Base < Matrix >{
public:
int rows;
int cols;
double *data;
Matrix(){}
Matrix( int in_rows, int in_cols ){
set_size( in_rows, in_cols );
}
void set_size( int in_rows, int in_cols ){
rows = in_rows;
cols = in_cols;
data = new double [rows*cols];
for( int i=0; i<rows*cols; i++ ) data[i] = 1.0;
}
Matrix( const Matrix & X );
const Matrix& operator=( const Matrix & X );
template< typename T1, typename T2 >
Matrix( const Glue<T1, T2> & X );
template< typename T1, typename T2 >
const Matrix & operator=( const Glue<T1, T2> & X );
};
template< typename T1, typename T2 >
class Glue : public Base< Glue<T1,T2> >{
public:
const T1 & A;
const T2 & B;
Glue( const T1 & in_A, const T2 & in_B ): A(in_A), B(in_B) {
}
};
template< typename T1, typename T2 >
inline const Glue< T1, T2 >
operator+( const Base<T1>&A, const Base<T2> & B ){
return Glue< T1, T2 >( A.get_ref(), B.get_ref() );
}
template< typename T1 >
struct depth_lhs{
static const int num = 0;
};
template< typename T1, typename T2 >
struct depth_lhs< Glue<T1, T2 > >{
static const int num = 1 + depth_lhs<T1>::num;
};
template< typename T1 >
struct mat_ptrs{
static const int num = 0;
inline static void
get_ptrs( const Matrix** ptrs, const T1 & X ){
{
ptrs[0] = reinterpret_cast<const Matrix*>(&X);
}
}
};
template< typename T1, typename T2 >
struct mat_ptrs< Glue<T1, T2> >
{
static const int num = 1 + mat_ptrs<T1>::num;
inline static void
get_ptrs( const Matrix** in_ptrs, const Glue<T1,T2>& X ){
mat_ptrs<T1>::get_ptrs(in_ptrs, X.A );
in_ptrs[num] = reinterpret_cast< const Matrix*>( & X.B );
}
};
template< typename T1, typename T2 >
const Matrix & Matrix::operator=( const Glue<T1,T2>& X ){
int i,j;
double sum;
int N = 1 + depth_lhs < Glue<T1,T2> >::num;
const Matrix* ptrs[N];
mat_ptrs< Glue<T1,T2> >::get_ptrs(ptrs,X);
int r = ptrs[0]->rows;
int c = ptrs[0]->cols;
set_size( r, c );
for( j=0; j<r*c; ++j ){
double sum = ptrs[0]->data[j];
for( i=1; i<N; ++i ){
sum += ptrs[i]->data[j];
}
data[j] = sum;
}
return *this;
}
int main(){
Matrix A(2,2);
Matrix B(2,2);
Matrix C(2,2);
Matrix D(2,2);
Matrix X(2,2);
X = A+B+C+D;
for( int i=0; i<4; i++ ) std::cout << X.data[i] << std::endl;
return 0;}
0 件のコメント:
コメントを投稿