2017-06-12 8 views
4

私はここに回答を書いた:https://stackoverflow.com/a/44481507/2642059accumulateを使用します。蓄積するFunctorの要件は何ですか?

:署名がバイナリファンクタの要件はそれということである const &

を持っている必要はありません

Ret op(const auto& a, const auto& b)しかし:

ファンクタのような署名付きバイナリでなければなりません

エンドイテレータを含むイテレータを無効にしたり、含まれる範囲の要素を変更したりしてはならない

蓄積されたオブジェクト自体がコンテナである場合、私はファンクタの要件については不明です。たとえば、許可されているようなものですか?

const auto range = { 0, 1, 2, 3 }; 
const auto Ret = accumulate(cbegin(range), cend(range), vector<int>(), [](auto& a, const auto& b){ 
    a.push_back(b); 
    return a; 
}); 

はい、私は、このソリューションの有効性について尋ねていますより良いソリューションを求めていないよ、これは単なるコピーであることを認識。

+2

私はそれが適用されているコンテナのイテレーターについて話していると確信しています。ファンクタは、反復処理中のコンテナを取得し、それを使って何かを行うことができます。順序付けられていない複数の集合を考えてみましょう。累積を使用して、その中の各要素の数を2倍にしようとすることができます。ハッシュ・マルチセットに要素を追加するとイテレータが潜在的に無効になるため、これは許されません。 –

+0

「範囲の要素を変更しない」と「範囲のイテレータを無効にしない」ため、技術的には正しいです。 cppreferenceの例でも、 'std :: string'を使った同様のスニペットが表示されています。 – Drop

+0

とにかくすべてのファンクタアプリケーションで結果のベクトルをコピーしているので、シグネチャには 'const&'もあります。しかし、関係のないいくつかの範囲を変更したとしても、それはすべて役に立ちます - 「範囲が関与する」とは、最初の2つの引数「accumulate」を介して渡されるものだけです – Ap31

答えて

3

私はworking draftがcppreferenceまたは何よりも明示的であると思う:

要素を変更することも、イテレータやサブレンジを無効にするものとどちらも範囲[first, last]binary_­opで。したがって、私はあなたが範囲[first, last]に影響を与えていないために、あなたの例では、有効であることを言うだろう

template <class InputIterator, class T> 
T accumulate(InputIterator first, InputIterator last, T init); 

template <class InputIterator, class T, class BinaryOperation> 
T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); 

accumulateは次のように宣言されている

一方、制約は、指定された範囲に対して完全に意味を持ちます。これは、2つのイテレータで定義するためです。
例として、ベクトルのイテレーターがbeginとendで、最後にの値をプッシュすることにしたとします。
ベクトルのサイズが変更されるとすぐに、accumulateは、いくつかのぶら下がっているポインタで動作します。いいえ。

関連する問題