
on 17.08.2009 at 21:24 joel wrote : ok i think i finally could explain my point i want to try to start from the beginning to be sure we are talking about the same thing consider following code template<typename expr_type> class mat_expr //general matrix expression { expr_type &ref() { return *(expr_type*)this; } //rude but efficient }; mat : public mat_expr<mat> //CRTP! {//matrix class //we use inheritance to state that 'mat' //specific interface //supports the 'matrix expression' //... //concept (and actually mat 'is-a' template<typename expr> //matrix expression) mat(const mat_expr<expr>&); //<-construct from expression }; template<typename expr1, typename expr2> mat_add_expr<...> operator+( //handle all /*general case*/ const mat_expr<expr1>&, //general const mat_expr<expr2>& //matrix ); //expressions mat_add_expr<...> is an expression that holds operands and performs the operation it inherits from mat_expr<mat_add_expr<...> > (CRTP) cool now we want to extend our type system to handle symmetric matrices efficiently template<typename expr_type> class symm_mat_expr : public mat_expr<expr_type> {}; //well, that's all class symm_mat : public symm_mat_expr<symm_mat> {//symmetric matrix //with appropriate interface template<typename expr> //copy from symmetric symm_mat(const symm_mat_expr<expr>&); //matrix expression, not }; //from general one template<typename expr1, typename expr2> symm_mat_add_expr<...> operator+( /*defining special case*/ const symm_mat_expr<expr1>&, const symm_mat_expr<expr2>& ); symm_mat_add_expr<...> is a full analogy to mat_add_expr<...> now we can write mat m1, m2, m3; symm_mat symm1, symm2, symm3; //... m1 = m2 + m3; //general case m1 = m2 + symm; //fall to general case symm1 = symm2 + symm3; //handled by special case symm1 = m1 + symm2; //hah! won't compile! the latter case won't compile because a sum of general matrix and symmetric matrix is not necessary symmetric rather it's a general matrix compiler helps to ensure this design by its overloading resolution rules i tried to show that this design is easily extendable (doing it in a natural c++ form) i hope this will make sense for you -- Pavel ps i have a crazy thought: matrix<double> typename matrix<double>::sparse typename matrix<double>::symmetric::sparse typename matrix<double>::sparse::symmetric //order doesn't matter //etc. please don't consider it serious!