2

STL を使用する上で必要と思われることの 1 つは、ローカル関数を指定する方法です。私が通常提供する関数の多くは、STL 関数オブジェクト作成ツール ( bind など) を使用して作成することはできません。関数オブジェクトを手動で作成する必要があります。

C++ 標準では、テンプレートのインスタンス化でローカル型を引数として使用することを禁止しているため、私が使用できた最善の方法は、小さなライブラリを作成することでした (関連する部分を表示するだけです)。

// library header
class MyFunctionBase<R,T>  
{  
 public:  
   virtual ~MyFunctionBase();  
   virtual R operator()(const T &) const=0;  
};    


class  MyFunction<R,T> 
{   
    MyFunctionBase<R,T> *b; 
 public: 
    ~MyFunction()
    {
       delete b;
    }
    virtual R operator()(const T &) const
    {
        return (*b)(T);
    } 
};


// source file
....

    class func: public MyFunctionBase  ...
    std::stl_alg(....    MyFunction(new funct));

これはいつも私には扱いにくいように思えました。ISO委員会の人々もそう信じて、C++にラムダを追加したと思います。

それまでの間、コンパイラはこの問題にどのように対処したのでしょうか? (特に Windows コンパイラ。)

少し明確になるかもしれない修正。変更ログ: 明確にするために 11 月 2 日を置き換え C++ 標準ではローカル クラスを関数オブジェクトとして禁止しているため

4

3 に答える 3

4

標準的な方法は「ファンクタ」です。基本的にはstructoperator()

例えば:

struct MyMinFunctor {
  bool operator()(const int& a, const int& b) { return a > b; }
};

vector<int> v;
sort(v.begin(), v.end(), MyMinFunctor());

これは構造体/クラスであるため、「binary_operator」などのサブクラスを作成したり、より高度なファンクターの状態を維持したりできます。

于 2008-11-02T05:41:27.897 に答える
1

Boost.Bind、Boost.Function、Boost.Lambda はあなたの友達です。

于 2008-11-02T20:35:49.137 に答える
1

C++0x では、ラムダを使用できます (前述のとおり):

for_each(container.begin(), container.end(),
  [](auto item) {
    // do something with item
  }
  );

これは、MS Visual C++ 2010 (現在 Community Tech Preview) および GCC 4.3.x (-std=c++0x コンパイラ フラグを使用) で既に利用可能です。ただし、ラムダがない場合は、次のタイプを提供するだけで済みます。

  1. デフォルトで構築可能
  2. コピー構築可能か
  3. 関数演算子のオーバーロードを定義します

二項関数オブジェクトを必要とするアルゴリズムもあれば、単項関数オブジェクトを必要とするアルゴリズムもあります。ベンダーの STL ドキュメントを参照して、バイナリ関数オブジェクトを必要とするアルゴリズムと単項関数オブジェクトを必要とするアルゴリズムを正確に確認してください。

TR1 (Boost.Bind および Boost.Function に基づく)のbindおよびの新しい実装も検討する必要があるかもしれません。function

于 2008-11-02T20:18:30.717 に答える