Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
4 / 3 / 1
Регистрация: 22.08.2014
Сообщений: 80
1

Заполнить vector алгоритмом accumulate

14.07.2017, 22:40. Просмотров 2402. Ответов 5
Метки нет (Все метки)

В книге Скотта Майерса "Эффиктивный STL" рекомендовалось использовать алгоритмы вместо циклов. Из функциональных языков (например haskell) я помню, что можно использовать foldl в качестве генератора списков, строк и прочих объектов. В C++ его аналогом является std::accumulate, но, изучив его работу, я столкнулся со следующими трудностями: для работы std::accumulate нужен перегруженный operator+(), который, по умолчанию, не является таковым для большинства контейнеров STL, соответственно, нужно либо создавать свою структуру и перегружать этот оператор, либо, по всей видимости, отказываться от использования алгоритма в данном контексте. Вторая, и куда более существенная, на мой взгляд, проблема состоит в практической применимости: стандартная перегрузка operator+() выглядит примерно так:
C++
1
T operator+(const T obj1, const T obj2) {...} //T - некий конкретный тип
То есть для каждого вызова этого оператора будет происходить несколько вызовов конструктора копирования: при передаче обоих объектов в функцию, наверняка - для создания объекта внутри и, потенциально, - для присваивания получившегося временного объекта некой переменной в вызывающей функции. Это не критично для небольших объектов и обычных чисел, но ужасно для любых контейнеров и объектов, которые их инкапсулируют. Стоит ли использовать std::accumulate для подобных целей, и, если да, то как это сделать эффективно?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.07.2017, 22:40
Ответы с готовыми решениями:

Применить accumulate к vector<pair<int, int>>
Привет. Как можно применить accumulate к vector&lt;pair&lt;int, int&gt;&gt;?

Как заполнить vector с клавиатуры?
Доброго времени суток! Пробую реализовать запись элементов в конец вектора. Как ввести в него...

Не получается заполнить vector данными
У меня в dll есть следующий класс. В main я пытаюсь создать вектор и заполнить его данными,...

Заполнить контейнер map и vector данными из файла
Текстовый файл содержит в себе информацию о пяти лифтах в виде: 12 900 first 10 600 second 15...

5
What a waste!
1576 / 1277 / 171
Регистрация: 21.04.2012
Сообщений: 2,677
14.07.2017, 22:55 2
Цитата Сообщение от VergilYamato Посмотреть сообщение
для работы std::accumulate нужен перегруженный operator+(), который, по умолчанию, не является таковым для большинства контейнеров STL
Оператор применяется к элементам контейнера, а не ко всему контейнеру. И это может быть любая бинарная операция, не обязательно +.

Цитата Сообщение от VergilYamato Посмотреть сообщение
То есть для каждого вызова этого оператора будет происходить несколько вызовов конструктора копирования
Аргументы можно и по ссылке принимать.
1
4 / 3 / 1
Регистрация: 22.08.2014
Сообщений: 80
14.07.2017, 23:27  [ТС] 3
Можете привести пример? Я написал что-то вроде:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<typename T> 
std::vector<T> & operator+(std::vector<T> &vec, T &obj)
{
    T new_obj = obj;
    vec.push_back(new_obj);
    return *vec;
}
 
int main()
{
    std::list<int> l{1,2,3,4};
    std::vector<int> v;
    std::accumulate(l.begin(), l.end(), v);
    return 0;
}
Но оно не работает.
0
What a waste!
1576 / 1277 / 171
Регистрация: 21.04.2012
Сообщений: 2,677
14.07.2017, 23:33 4
VergilYamato, вы что сделать то хотите?
std::accumulate - это обычный reduce для диапозона. Можно например l "заредьюсить":
C++
1
2
std::list<int> l{1,2,3,4};
int sum = std::accumulate(l.begin(), l.end(), 0); // 1 + 2 + 3 + 4
http://en.cppreference.com/w/c... accumulate
0
4 / 3 / 1
Регистрация: 22.08.2014
Сообщений: 80
14.07.2017, 23:39  [ТС] 5
Первая цель была в том, чтобы с помощью std::accumulate нечётные числа из одного вектора скопировались в другой, потом задался более глобальной целью: заполнение изначально пустого вектора определёнными значениями.
0
What a waste!
1576 / 1277 / 171
Регистрация: 21.04.2012
Сообщений: 2,677
14.07.2017, 23:47 6
Лучший ответ Сообщение было отмечено VergilYamato как решение

Решение

Цитата Сообщение от VergilYamato Посмотреть сообщение
помощью std::accumulate нечётные числа из одного вектора скопировались в другой
Тут accumulate не подойдёт конечно.
Есть transform: http://en.cppreference.com/w/c... /transform

Добавлено через 3 минуты
Хотя вру, скорее copy_if: http://en.cppreference.com/w/cpp/algorithm/copy
C++
1
2
3
4
std::list<int> l{1,2,3,4};
std::vector<int> v;
std::copy_if(l.begin(), l.end(), std::back_inserter(v),
             [] (auto const& v) { return v % 2 == 1; });
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.07.2017, 23:47

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Заполнить vector<char> с клавиатуры буквами/спец. символами
Всем добрый день! Немного(много) туплю. Подскажите, как заполнить вектор с клавиатуры буквами/спец....

Используя контейнер vector заполнить структуру как таблицу и вывести ее
создать класс с переменными типа int,float,string: Через вектор заполнить как таблицу и вывести ее...

Как заполнить std::vector с консоли, не создавая новую переменную?
Добрый вечер, каким образом можно заполнить вектор с консоли, не создавая новую переменную? ...

accumulate if?
Какой алгоритм способен найти сумму элементов, удовлетворяющих какому-либо условию?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.