5

STLのgenerate_nアルゴリズムへの入力として次の構造体を使用しています。

struct GenerateNumber {     
    GenerateNumber () : i(0) {}
    int operator () (void) {        
        return  i++;
    }
private:
    int i;
};

このファンクターを使用するコードの例は次のとおりです。

std::vector <int> v1 (3);
std::vector <int> v2 (3);
GenerateNumber generateNumber;
std::generate_n (v1.begin (), 3, generateNumber);
std::generate_n (v2.begin (), 3, generateNumber);

ただし、結果として、を含むのではなく、との両方が含まv1れます。ブレークポイントを使用して、コンストラクターが1回だけ呼び出されることを確認しました(コンストラクターが2回以上呼び出されることは意味がないことはわかっていますが、とにかくチェックしました)。v2{0,1,2}v2{3,4,5}GenerateNumber

静的にすることでこれを解決できることは知っていiますが、この動作は理解できません。i連続する呼び出し間での値が保持されないのはなぜですか?

4

2 に答える 2

8

ジェネレータオブジェクトは、に渡されるときにコピーされgenerate_nます。を使用してみてくださいstd::ref、すなわち

std::generate_n(v1.begin(), 3, std::ref(generateNumber));
std::generate_n(v2.begin(), 3, std::ref(generateNumber));

編集:std::refこれはC++11でのみ使用可能であることに注意してください。TR1でとして導入されstd::tr1::ref、boostでもとして利用できますboost::ref

于 2012-05-13T09:48:34.043 に答える
3

std :: generate_nは、ファンクターを値で取得します。つまり、そのコピーを作成します。コピーコンストラクターが呼び出されていることを確認しなかった可能性があります。

がない場合std::ref、および問題が例のようにローカライズされている場合は、ファンクターを変更して、次の呼び出しのスコープ内に設定されたカウンターへの参照を取得できますstd::generate_n

struct GenerateNumber {     
    GenerateNumber (int& i) : struct GenerateNumber {     
    GenerateNumber () : i(0) {}
    int operator () (void) {        
        return  i++;
    }
private:
    int& i;
};

int main() {
  int counter = 0;
  std::vector <int> v1 (3);
  std::vector <int> v2 (3);
  GenerateNumber generateNumber(counter);
  std::generate_n (v1.begin (), 3, generateNumber);
  std::generate_n (v2.begin (), 3, generateNumber);

}
于 2012-05-13T09:49:24.790 に答える