bind2nd в цикле for_each

Есть кое-что, что я в настоящее время не могу обернуть вокруг себя.
Я ожидал вывод, где каждый элемент увеличивается на 1.
Очевидно, что это не так.

Посмотрев ближе, я думаю, что это потому, что возвращаемое значение функции bind2nd отбрасывается; то есть функция не изменяет элементы контейнера.

Правильно ли мое мышление? Может ли кто-нибудь подтвердить или предоставить правильное объяснение того, что контейнер не был изменен?

#include <vector>
#include <iostream>
#include <algorithm>
#include <functional> using namespace std; void printer(int i) {
cout << i << ", "; } int main() {
int mynumbers[] = { 8, 9, 7, 6, 4, 1 };
vector<int> v1(mynumbers, mynumbers + 6);
for_each(v1.begin(), v1.end(), bind2nd(plus<int>(), 1));//LINE I
for_each(v1.rbegin(), v1.rend(), printer);//LINE II
return 0; }

1

Решение

for_each(v1.begin(), v1.end(), bind2nd(plus<int>(), 1));

эквивалентно как:

for (auto first = v1.begin(); first != last; ++first) {
plus<int>()(*first, 1); // i.e. *first + 1;
}

Как вы видели, это действительно ничего не изменит.

Вы можете использовать функтор, который изменяет значение с std::for_each:

std::for_each(v1.begin(), v1.end(), [](int &n){ n += 1; });
1

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

Декларация operator() из template <typename T> std::plus является

T operator()(const T& lhs, const T& rhs) const;

то есть он не изменяет входные аргументы. Тебе нужно std::transform:

std::transform(v1.cbegin(), v1.cend() v1.begin(), std::bind2nd(std::plus<int>(), 1));

или вы можете использовать лямбду, которая делает измените его входной аргумент:

std::for_each(v1.begin(), v1.end(), [] (int& x) { ++x; });
2

std::for_each не изменяет последовательность ввода.

Чтобы применить изменения к каждому элементу контейнера, используйте std::transform вместо:

transform(v1.begin(), v1.end(), v1.begin(), bind2nd(plus<int>(), 1));
//                              ~~~~~~~~~^ puts the results back into the input sequence
1
По вопросам рекламы [email protected]