2011-08-25 6 views
3

std::transformまたはstd::partial_sumのような 'ストリーミング'アルゴリズムは、同じ場所から読み書きできますか?ForwardIteratorとOutputIteratorをC++標準アルゴリズムで同じにすることはできますか?

たとえば、次のコードはgccで動作しますが、「事故」ではなく、コンパイラがコードを分解して最適化することが自由であるかどうかはわかりません。

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

int main() 
{ 
    int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 
    std::vector<int> vec(arr, arr + sizeof(arr)/sizeof(arr[0])); 
    std::partial_sum(vec.begin(), vec.end(), vec.begin()); 
    for(std::vector<int>::iterator iter = vec.begin(); iter != vec.end(); iter++) 
    std::cout << *iter << std::endl; 
    return 0; 
} 

答えて

1

はい、これは正常に動作します。あなたは同じ量の回答要素のためにあなたのソースを上書きします。

例えば、

int square(int x) { return x*x; } 
std::transform(vec.begin(), vec.end(), vec.begin(), square); 

は、その場所にVECで各番号を二乗でしょう。

3

はい、絶対に、イテレータが最初に読み書きを許可する限り(たとえば、明らかにstd::coutから読み取ることはできません)。一般的なパターンは、transformを使用して、ベクターをその場で突然変異させることです。

+1

質問の 'partial_sum'の例では、アルゴリズムの実装は最初に新しいベクトルを埋めて、その内容を元の' vec'にコピーするだけです。さもなければ、置き換えが「適切な位置で」行われた場合、計算された最初の部分的な合計はベクトルの元の要素を置き換え、次の合計に影響を与え、代わりに '0,1,3,8,17 ...'になります期待されている '0,1,3,6,10 ...'の数(これは@ w00teの例では問題ではないでしょう)。標準はそれが正しい方法で動作することを保証していますか? –

+0

@Marek私は従いません。 'partial_sum'は新しいベクトルを埋めることに依存しません。操作は自在に行うことができ、明示的な実装はまったく同じです(例:[cplusplus.com](http://cplusplus.com/reference/std/numeric/partial_sum/)を参照)。 –

+0

@Marekさらに、標準ではこれが実際に保証されています(例§26.4.3.5など)。そして、いいえ、最後のインデックスから始める必要はありません。実際、*あなたは*できません:インデックスはありません、アルゴリズムは(非ランダムアクセス)イテレータで動作します! –

関連する問題