0

単純な問題がありますが、C++ でファンクターを使用したことがないため、解決方法がわかりません。

私はそのようなことをしたいです(それは単なる例です):

class MyClass
{
    void applyFunction(myFunction);  /* WRONG SYNTAX */
    double *_x;
    unsigned int *_size;
};

void MyClass::applyFunction(myFunction) /* WRONG SYNTAX */
{
    for (unsigned int i = 0; i < _size; ++i)
        myFunction(_x[i], 10.);
}

class OtherClass
{
    void myFunction1(double x, double lim);
    void myFunction2(double x, double lim);
    std::vector _v;
};

void OtherClass::myFunction1(double x, double lim)
{
    _v.clear();
    if (x > lim)
        _v.push_back(x);
}

void OtherClass::myFunction2(double x, double lim)
{
    _v.clear();
    if (x < lim)
        _v.push_back(x);
}

int main()
{
    MyClass myClass;
    OtherClass otherClass;
    myClass.applyFunction(otherClass.myFunction1); /* WRONG SYNTAX */
    std::cout<<otherClass._v.size()<<std::endl;
    myClass.applyFunction(otherClass.myFunction2); /* WRONG SYNTAX */
    std::cout<<otherClass._v.size()<<std::endl;
        return 0;
}

functors/std::functions を使用する正しい構文は何ですか?

どうもありがとうございました !

4

2 に答える 2

4

これにファンクターを使用したいというあなたの言葉に耳を傾けます。にやにや笑いながら、これをコンパイルできるようにする構文を見つけるだけでなく、これを「正しい」方法で行いたいと思います(おそらく実行して、おそらくやりたいことを実行します)。

この場合、標準ライブラリには、(特に C++11 で) 行っていることの多くをサポートするアルゴリズムが既に含まれています。いくつかの条件を満たすデータをターゲット ベクトルにコピーするには、std::copy_if(C++98/03 にはありませんが、比較の意味を逆にして を使用する必要がありますstd::remove_copy_if)。

これを使用すると、コードは次のようになります。

template <class T>
class less_than {
    T limit;
public:
    less_than(T lim) : limit(lim) {}
    bool operator()(T const &val) { return val < limit; }
};

std::copy_if(source.begin(), 
             source.end(), 
             std::back_inserter(target), 
             less_than<int>(10));

ただし、C++11 が利用可能な場合は、代わりにラムダを使用する方がおそらく便利です。

std::copy_if(source.begin(), 
             source.end(), 
             std::inserter(target), 
             [](int v) { return v < 10;});

ラムダは基本的に、コンパイラに無名ファンクター クラスを生成させる方法にすぎないため、両者の間に大きな違いはありませんが、ラムダを使用すると明らかにかなりのタイピングが節約されます。

C++03 に行き詰まっている場合は、基本的に比較を反転するだけです。

template <class T>  
class greater_than { 
    T limit;
public:
    bool operator()(T const &val) {
        return val > limit;
    }
};

std::remove_copy_if(src.begin(), 
                    src.end(), 
                    std::back_inserter(dst),
                    greater_than(10));

別の方法として、独自のコードを簡単に作成することもできますcopy_if。C++98/03 から除外されたのは、主に見落としによるものであり、言語が提供しないものやそのようなものを必要とするためではありません (私が思い出したように、すべての正確に正しい境界条件は少し難しい場合があります)。

std::less価値のあることとして、標準ライブラリにはandがあることにも注意する必要があります。std::greaterそのため、上で示したless_thanandgreater_thanファンクタは実際には必要ありません。残念ながら、これらは比較を行うだけなので、ここで行っているように使用するには、定数と比較するために使用std::bind1stまたは取得する必要があります。std::bind2nd

std::remove_copy_if(src.begin(),
                    src.end(),
                    std::ostream_iterator<int>(std::cout, "\n"),
                    std::bind1st(std::less<int>(), 10));
于 2012-04-04T03:54:49.683 に答える
1
void applyFunction(std::function<void(double, double)>);
// ...
applyFunction(std::bind(&OtherClass::myFunction1, &otherClass));
于 2012-04-04T03:23:52.037 に答える