なんでもかんでもfor_eachやtransformといった高階関数で記述するのがマイブームな今日この頃、こんなものを考えた。
こんな状況があったとする。
class C{ //クラスC public: void Hi( void){ cout<< "hi!"<<endl; } }; class B{ //クラスB public: B( void ){ _c = new C; } ~B(void){ delete _c; } C* getC( void ){ return _c; } C* _c; }; class A{ //クラスA public: A( void ){ _b = new B; } ~A( void ){ delete _b; } B* getB( void ){ return _b; } B* _b; };
クラスAのポインタのコンテナがあるとき、その各々について、Aの中のBの中のCの中のHi()を呼び出したい場合は、本来ならこう呼ばなくてはならないものを(ごめんなさいVS2008SP1です)
for each( A* ia in ca ){ ia->getB()->getC()->Hi(); }// ia
こういうものを考えることにより、
template< class Fnc1, class Fnc2, class Fnc3 > struct NestCall_t { NestCall_t( Fnc1 fc1, Fnc2 fc2, Fnc3 fc3 ) : _fc1(fc1), _fc2(fc2), _fc3(fc3) {} typename Fnc3::result_type operator()( const typename Fnc1::argument_type arg ) const { return _fc3( _fc2( _fc1( arg ) ) ); } Fnc1 _fc1; Fnc2 _fc2; Fnc3 _fc3; }; template< class Fnc1, class Fnc2, class Fnc3 > NestCall_t< Fnc1, Fnc2, Fnc3 > NestCall( Fnc1 fc1, Fnc2 fc2, Fnc3 fc3 ){ return NestCall_t< Fnc1, Fnc2, Fnc3 >( fc1, fc2, fc3 ); }
NestCallを使うと1行でこう書ける。
std::for_each( ca.begin(), ca.end(), NestCall( mem_fun( &A::getB ), mem_fun( &B::getC ), mem_fun( &C::Hi ) ) );
(結局数日前に書いたHillwayAdapterの本質はこれだった。)あるいは俺が無知なだけですでにこういうものあるのだろうか。ていうかNestCall使ったほうがコード量増えてるじゃねーかっつう話もあるが…(汗)、少なくとも可読性はあがってるはず。(あがってねーよっつう噂も、、)
上記のものは3段階呼び出し特化バージョンだが当然2段階でも4段階でも、あるいはbindと組み合わせればHi()に限らずいろんな関数が呼び出せそうな予感。