1

ファンクターの「力」を理解しようとしています。

さて、これらは関数へのポインターですが、実装されていない他のクラスではoperator()できないことで、それらでできることは何でしょうか?

例えば ​​:

#include <iostream>
#include <assert.h>
#include <vector>
using namespace std;


class MultiplyBy
{
    private:
        int factor;

    public:
        MultiplyBy(int x) : factor(x) {}

        int operator () (int other) const
        {
            return factor * other;
        }
};


int main()
{

    MultiplyBy temp(5);
    int myResult = temp(5);  // now myResult holds 25
    cout << myResult << endl;
    return 0;
}

そして、私たちは彼の他の友人を連れて行きます

class MultiplyOther
{
    private:
        int factor;
    public:
        MultiplyOther(int x) : factor(x) {}
        int invokeMultiplyMe(int _other)
        {
            return _other * factor;
        }
};

そして同じことをします:

int main()
{
    // MultiplyOther

    MultiplyOther notFunctor(4);
    int myOther = notFunctor.invokeMultiplyMe(3);
    cout << myOther << endl;
    return 0;
}

そして、次のようになります。

25
12

では、ファンクターの真の力とは何でしょうか? 両方のクラスが状態を保存しますか、それともここで何か不足していますか?

4

3 に答える 3

4

1 つは、何かを呼び出さなければならないことを知るだけでよいアルゴリズムなどで使用できる統一された署名を持っていることです。

あなたの例では、 のインスタンスは、を取り、それを返すもの (または /convertible から に構築可能な型)MultiplyByを呼び出すことを期待する任意のコードで使用できます。2 番目の例を使用するには、コードにメソッドの知識が必要です。intintinvokeMultiplyByMe

質問に記載されているように、ファンクターは関数へのポインターではないことに注意してください。これらは、関数呼び出しの構文でインスタンスを呼び出すことができるクラスです。

于 2012-08-26T13:00:36.150 に答える
1

ファンクタにはクラスに対する特別なプロパティはありませんが、より高い機能を持つ関数として使用できます。通常、関数は状態を持つことができず、(静的変数を使用して) 持つ場合、その状態はすべての関数呼び出しで共有されます。\

ファンクターはクラスのすべてのプロパティ (特に状態) を持ちますが、関数として使用できます。良い例は、STL アルゴリズムに使用されるファンクターです。

class Add
{
  public:
    Add(){sum = 0;};
    void operator()(int i)
    {
        sum += i;
    }
    int getSum(){return sum;};

    private:
    int sum;
}

int main()
{

std::vector<int> vint;
vint.push_back(2);
vint.push_back(3);
vint.push_back(4);
}

Add adder;

adder = std::for_each( vint.begin(); vint.end(), adder);

cout << adder.getSum();
于 2012-08-26T13:01:10.100 に答える
0

「したがって、それらは関数へのポインターです」-関数ポインターとファンクターは完全に異なります。前者は、元の関数への単なるポインタです。状態はありません。ただし、ファンクターまたは関数オブジェクトは状態を保持します。Functorは、operator()を定義する任意のクラスです。したがって、その種のクラスの任意のオブジェクトは、関数の方法で呼び出すことができます。

C++入門書からのコードスニペット...

template<class T>
class TooBig
{
    private:
    T cutoff;
    public:
    TooBig(const T & t) : cutoff(t) {}
    bool operator()(const T & v) { return v > cutoff; }
};

このクラスを使用すると、カットオフ値が異なる複数のオブジェクトを作成できます。TooBig cutoff1(10); TooBig cutOff2(20);

ファンクターを使用するのに最適な場所の1つは、テンプレートです。たとえば、リストテンプレートを使用します。これには、引数からtrueを返すリスト内の値を削除するremove_if関数があります。

リストlist1; //いくつかの値があるとしましょうlistlist2; //いくつかの値があるとしましょう

ここで、list1.remove_if(cutoff1);を呼び出します。// list1のすべての要素を適用し、cutOff1に格納されている値より大きい要素を削除します。list2についても同様です。

どうも!

于 2012-08-26T13:29:21.110 に答える