分配法則で掛け算を先に行う。
分配法則とは、以下のような法則である。
a * ( b + c ) = a * b + a * c
( b + c ) * d = b * d + c * d
まあ中学校あたりでやることなのでいちいち説明も必要はないと思うけど。
で、実際に計算する場合は左辺が足し算1回掛け算1回に対し、右辺が足し算1回掛け算2回なのでいちいち分解したりしないのが普通で、場合によっては右辺の状態を因数分解して左辺にしてから計算する場合もあるだろう。
しかし、実際にはいちいち分解しないわけにいかない場合がある。カッコの中の足し算が線形演算子だった場合だ。線形演算子の場合は分配法則は寧ろ足し算の定義であって実際に演算子同士の足し算を直接出来るわけでない。ので実際に計算する場合は一旦分解してそれぞれ演算子を作用させてからあとで演算結果を足すわけになる。
というわけで、もし線形演算子クラスみたいなのをつくろうと思うと、分配法則で掛け算を先に計算して最後に足し算をするような設計にする必要がある。
//足し算の表現クラス template< class L, class R > class Exp_Plus { public: Exp_Plus( const L& l, const R& r ):m_l(l),m_r(r){} const L& l()const{ return m_l; } const R& r()const{ return m_r; } private: const L m_l; const R m_r; }; //掛け算の表現クラス template< class L, class R > class Exp_Multi { public: Exp_Multi( const L& l, const R& r ):m_l(l),m_r(r){} private: const L m_l; const R m_r; }; //各種演算定義 template< class L, class R > Exp_Plus< L, R > operator+( const L& l, const R& r ) { return Exp_Plus< L, R >( l, r ); } template< class L, class RL, class RR > Exp_Plus< Exp_Multi< L, RL >, Exp_Multi< L, RR > > operator*( const L& l, const Exp_Plus< RL, RR >& plus ) { return Exp_Plus< Exp_Multi< L, RL >, Exp_Multi< L, RR > >( Exp_Multi< L, RL >( l, plus.l() ), Exp_Multi< L, RR >( l, plus.r() ) ); } template< class LL, class LR, class R > Exp_Plus< Exp_Multi< LL, R >, Exp_Multi< LR, R > > operator*( const Exp_Plus< LL, LR >& plus, const R& r ) { return Exp_Plus< Exp_Multi< LL, R >, Exp_Multi< LR, R > >( Exp_Multi< LL, R >( plus.l(), r ), Exp_Multi< LR, R >( plus.r(), r ) ); }
考え方として、まず足し算があったら足し算の表現クラスに一時格納し、その表現クラスとの掛け算が着たら、中身を出してそれぞれ掛け算の表現クラスを生成し、そしてまた足し算表現クラスにいれてしまう。
で、上記はあくまで式を生成しただけで実際の演算は行っていないので実用上はさらにそれぞれgetメソッドみたいなのを付けてその中で演算を実装してやる必要がある。そのあたりは実際の演算子の内容によるので今回は割愛します。