2

VisualStudio2012で関数オブジェクトを使用できません。

単純なものを作成しstd::vector、0〜9を追加しintsて、関数オブジェクトを使用してその合計を作成したいと思いました。私のクラス定義(インライン):

template <class T>
class Sum {
private:
    T val;
public:
    Sum (T i = 0) : val(i) {
    }

    void operator()(T x) { 
        val += x; 
    }

    T result() const { 
        return val; 
    }

    ~Sum() {
        std::cout << "Invoked destructor! val: " << val << " for this: " << this << std::endl;
    }
};

私の主な機能:

int main(int argc, char *argv[]){

    Sum<int> s;

    int contents[] = {1,2,3,4,5,6,7,8,9};

    std::vector<int> vec = std::vector<int>(contents, contents + 9);

    std::for_each(vec.begin(), vec.end(), s);

    std::cout << "Sum of all numbers: " << s.result() << std::endl;

    return 0;
}

デストラクタからの出力を使用して、次のようになります。

Invoked destructor! val: 45 for this: 003BFDA4
Invoked destructor! val: 45 for this: 003BFDE0
Sum of all numbers: 0
Invoked destructor! val: 0 for this: 003BFEFC

これはVSのバグですか?デバッガーを使用して実行すると、項目が合計されます45が、その直後にデストラクタが呼び出されます。私は何が間違っているのですか?

編集:

これは、StroustrupのThe C++ Programming Language18.4章の例です。正確にコピーしたので、うまくいかなかったのではないかと思いました。

4

1 に答える 1

5

問題はstd::for_each、ファンクター引数を値で受け入れることです。これは、元のオブジェクトのコピーで機能することを意味します。良いニュースは、変更された状態を保持するコピーも返すことです。これでうまくいくはずです:

Sum<int> s1 = std::for_each(vec.begin(), vec.end(), s);
std::cout << "Sum of all numbers: " << s1.result() << std::endl;

または、valファンクター内のを変数への参照にすることもできます。

template <class T>
class Sum {
private:
    T& val;
public:
    Sum (T& i) : val(i) {
    }
// ...

さて、これはうまくいくはずです:

int i = 0;
Sum<int> s(i);
std::for_each(vec.begin(), vec.end(), s);
std::cout << "Sum of all numbers: " << s1.result() << std::endl;

ただし、ぶら下がり参照を作成しないように、 の有効期間iが十分に延長されていることを確認する必要があります。Sum<T>::val

于 2013-03-19T20:45:23.507 に答える