2
for_each(ivec.begin(),ivec.end(),
        []( int& a)->void{ a = a < 0 ? -a : a; 
    });

transform(ivec.begin(),ivec.end(),ivec.begin(),
        [](int a){return a < 0 ? -a : a;
    });

私は現在ラムダを学習していますが、上記で投稿した2つの実装がどのように異なるのか興味がありますか?

4

3 に答える 3

5

表示する2つの実装は、論理的には異なりません(リターンを追加することで、最初のバージョンが正しく取得されると想定しています)。最初のものはその場で要素を変更し、最後のものはその要素を新しい値で上書きします。

私が見る最大の違いは、それを再実装するラムダの代わりにtransformパスすることができるということです。abs

于 2013-01-11T02:04:32.073 に答える
4

transform関数型言語では、と呼ばれるものmapです。つまり、入力範囲内のすべての要素に関数を適用し、出力を出力範囲に格納します。(したがって、通常、入力を変更せず、代わりに出力の範囲を格納することを目的としています)

for_each適用された関数からの戻り値を破棄するだけです(入力が変更される可能性があります)。

それが主な違いです。それらは似ていますが、異なる目的のために設計されています。

于 2013-01-11T02:02:58.047 に答える
2

この最初のバージョン:

for_each(ivec.begin(),ivec.end(),
      []( int& a)->void{ a = a < 0 ? -a : a; 
});

ラムダ関数を呼び出すことで機能します

 []( int& a)->void{ a = a < 0 ? -a : a; }

範囲内の要素ごとに1回、範囲内の要素を引数として渡します。したがって、要素の値を直接変更することにより、要素をインプレースで更新します。

この2番目のバージョン:

transform(ivec.begin(),ivec.end(),ivec.begin(),
    [](int a){return a < 0 ? -a : a;
});

ラムダ関数を適用することで機能します

[](int a){return a < 0 ? -a : a;}

からの範囲内の各要素に、一連の値を生成ivec.begin()ivec.end()、それらの値を。から始まる範囲に書き戻しますivec.begin()。これは、範囲の元の内容を、関数を各配列要素に適用することによって生成された値の範囲で上書きすることを意味します。そのため、要素はインプレースで変更されるのではなく、上書きされます。ただし、正味の効果は元の効果と同じfor_eachです。

お役に立てれば!

于 2013-01-11T02:04:30.563 に答える