2

std :: for_eachとオーバーロードされたoperator()を持つオブジェクトを使用して、ベクトルコンテンツに関するデータを蓄積するとします。

#include <iostream>
#include <vector>
#include <algorithm>

struct A{
    int a;
    A(): a(0){}

    void operator()(int i) {
        if(i)   a++;
        std::cout << "a:" << a << std::endl;
    }
};

int main(int argc, char *argv[]) {
    //test data
    std::vector<int> vec;
    vec.push_back(1);
    vec.push_back(1);
    vec.push_back(0);

    //accumulator
    A accum;

    std::for_each(vec.begin(), vec.end(), accum);
    std::cout << "non-zero elements:" << accum.a << std::endl;

    return 0;
}

この出力

a:1
a:2
a:2
non-zero elements:0

なぜnon-zero elements0なのですか?

4

4 に答える 4

6

std::for_each()は3番目の引数を参照しないため、のコピーaccum作成されます。

std::coutステートメントを追加するとA::A()、この動作を確認できます。

注意点として、この特定の問題は次を使用して解決できますstd::count_if()

std::cout << "non-zero elements: "
          << std::count_if(vec.begin(),
                           vec.end(),
                           [](const int i) { return i != 0; })
          << std::endl;
于 2012-08-18T10:29:10.953 に答える
2

通常、 1標準ライブラリによって提供されるアルゴリズムは、ファンクターを参照ではなく値で取得します。したがって、渡したファンクターは変更されていないため、「外部から」最終状態を検査することはできません。

幸い、for_eachすべての要素に適用された後、ファンクターのコピーが返されるため、実行する必要があるのは次のとおりです。

accum = std::for_each(vec.begin(), vec.end(), accum);

ここでは2つのコピーが関係しているため、通常はコピーが安価な「些細な」ファンクターを使用することをお勧めします。コンパイラーによって生成されたものが機能しない場合は、コピーコンストラクターを提供することが重要です。

それでも、他の人が指摘しているように、実行しているタスクにはより適したアルゴリズムがあります。


  1. Nitpickerのコーナー:実際にすべてをチェックしたわけではありませんが、これは私が使用したすべてのもので見た「通常の」動作のようです。
于 2012-08-18T10:30:19.127 に答える
1

標準ライブラリアルゴリズムは通常、引数ファンクターをコピーするため、その状態になっている可能性は表示されません。

あなたは本当にここで間違ったアルゴリズムを使おうとしています。

for_eachシーケンス内のすべての要素に操作を適用することを目的としており、それ以上のものはありません。

シーケンスを繰り返し処理して、ある種のデータを蓄積したい場合は、...を使用する必要がありますstd::accumulate。:)

アルゴリズムは「状態」という1つの追加パラメーターを取り、アルゴリズムが終了するとこの状態が返されます。

于 2012-08-18T10:35:58.383 に答える
0

他の人が述べているように、ファンクターを参照として使用しないため、のさまざまなインスタンスAが使用されます。次のアドレスを出力するようにコードを少し変更するstd::for_eachと、これを確認できます。A::a

a:1  @0xbf86902c
a:2  @0xbf86902c
a:2  @0xbf86902c
non-zero elements:0  @0xbf869050
于 2012-08-18T10:40:21.503 に答える