トップページ
ひらく | たたむ | ページトップ
↓マウスで反転選択した文字を検索
C++
   
ページ内検索 ページ外検索
検索したい文字を入力して
ENTERを押すと移動します。
\n
[ トップページ ]
[ ____CommandPrompt ] [ ____JScript ] [ ____MySQL ] [ ____Cygwin ] [ ____Java ] [ ____Emacs ] [ ____Make ] [ ____Perl ] [ ____Python ] [ ____OpenGL ] [ ____C# ] [ ____StyleSheet ] [ ____C++ ] [ ____Winsock ] [ ____Thread ] [ ____VisualStudio ] [ ____C ] [ ____Win32API ] [ ____Lua ] [ ____PhotoShop ]
ヘッダ検索

___

■ FunctionObject(ファンクタ)


  DESC
    function(関数) object といわれるもので
    Cでいうコールバック関数ポインタの働きをする
      
    関数のように動作する Object のこと
    演算子 overload のうち、() をoverload したもの

  POINT
    使いどころ
    より優れたコールバックを記述すること.
    C などの手続き型プログラミング言語にコールバックは関数へのポインタによって実現することができる
    コールバックの内外に状態変数を渡すことが難しい

    strategy デザインパターンの完全な具現化であり、抜き差し可能な振る舞いを促進するもの。
    STL では Template による. Functor を多用している


      operator=()
      operator()()
      
      // 関数 object
      class Cout()
      {
        public:
          void operator()( int num ){ 
              cout < <  num < <  endl;
          }
      };

      // Client  
      int main(){
          Cout func;
          func( 5 );   // call back を呼ぶ
      }
      

      // template 化する
      template <  class T >
      class Cout()
      {
        public:
          void operator()( T num ){ cout < <  num < <  endl; }
      };      

      std::for_each( c.begin(), c.end(), Cout< float>() );      
      -> 
      どんな std:cout() に対応できるものならば、すべて可能 ( Template の原則 . )
      STL と組み合わせることで、より強力な tool になる


    // cpp の callback との比較
    int comp_func( int a, int b )
    {
      return a > b;
    }

    // functor
    class compCls
    {
    public:
      operator()( int a, int b ){
        return a > b;
  }
    };

    // 宣言
    template < class compFunctor>
    void sort( int *p, int nr, compFunctor c );
    
    // usr
    int main()
    {
      int data[] = {0, 1, 2};
      compCls func;      // 上記 cls を使用
      sort( data, 3, func );

      // 使用する際は 
      func(); とする ?
    }     

    // 二つの要素の順序関係を定義するコールバック関数を用いて並べ替えを行うルーチンの例
    /* Callback function */
    int compare_function(int A, int B) {
      return (A <  B);
    }    
    
    // C の並べ替え関数の定義
    void sort_ints(int* begin_items, int num_items, int (*cmpfunc)(int, int) );    


   int main() {
       int items[] = {4, 3, 1, 2};
       sort_ints(items, sizeof(items)/sizeof(int), compare_function);
   }    

   // C++ では通常の関数の代わりに、operator() メンバー関数を定義して 関数呼び出し演算子をオーバーロードすることで、
   // 関数オブジェクトを利用できる
   class compare_class {
     public:
     bool operator()(int A, int B) {
       return (A <  B);
     }
   };

    // C++ の並べ替え関数の定義 -> template になっている. 
    template < class ComparisonFunctor> 
    void sort_ints(int* begin_items, int num_items, ComparisonFunctor c);


    int main() {
        int items[] = {4, 3, 1, 2};
        compare_class functor;
        // PtrFunc ではなく, Object をわたす.
        // Object なので, VarMem, FuncMem にアクセス可能.
        sort_ints(items, sizeof(items)/sizeof(int), functor);
    }


    // Functor を別の用途で使ってみる. 
    functor_class Y;
    int result = Y( a, b );    

    
    // Inline 化できるため, C の PtrFunc よりも性能がよい. 
    struct IncrementFunctor {
      void operator()(int&i) { ++i; }
    };

    // 通常の関数による Increment 
    void increment_function(int&i) { ++i; }

    template<  typename InputIterator, typename Function >
    Function for_each(InputIterator first, InputIterator last, Function f) {
      for ( ; first != last; ++first) {
        f(*first);
      }

      return f;
    }

    int A[] = {1, 4, 2, 8, 5, 7};
    const int N = sizeof(A) / sizeof(a[0]);

    for_each(A, A + N, IncrementFunctor());
    for_each(A, A + N, increment_function);    


    // 状態も保持できる.     
    #include < iostream>
    #include < iterator>
    #include < algorithm>

    // 要はクラス名が関数名になる.
    class countfrom 
    {
      private:
        // 状態. 
        int count; 
      public:
        countfrom(int n) : count(n) {}
        int operator()() { return count++; }
    };

    int main() {
      std::generate_n(std::ostream_iterator< int>(std::cout, "\n"), 11, countfrom(10));
      return 0;
    }


NINJAIDX 12