Visual Studio — объекты функций C ++ не могут создать сумму с использованием std :: for_each (VS2012)

У меня возникли проблемы с использованием объектов-функций в Visual Studio 2012.

Я создал простой std::vector, добавил ints 0-9 и хотел создать сумму, используя объект функции. Мое определение класса (встроенное):

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 но сразу после этого деструктор вызывается. Что я делаю неправильно?

РЕДАКТИРОВАТЬ:

Это пример из Страуструпа The C++ Programming LanguageГлава 18.4. Я просто подумал, что это не сработало, потому что я его точно скопировал.

2

Решение

Проблема в том, что 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 свисающая ссылка.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]