Как суммировать элементы std :: set

Я пытаюсь найти сумму элементов в наборе, и мне было интересно, как найти хорошие способы ее найти.
Я построил два класса, один с именем Customer, а другой с Item, я хочу написать функцию, которая будет вычислять общую сумму, которую клиент должен заплатить за свои продукты, перечисленные в std :: set из типа Item.
Вот декларация моего набора:

set<Item> _items;

Класс предмета:

private:
string _name;
string _serialNumber; //consists of 5 numbers
int _count=0; //default is 1, can never be less than 1!
double _unitPrice; //always bigger than 0!

Функция в классе Item для суммирования цены товара:

double Item :: totalPrice() const
{
return _count*_unitPrice;
}

Вот функция, которую я пытаюсь написать, которая суммирует все мои элементы:

#include <numeric>
#include "Customer.h"double Customer::totalSum() const
{
double sum = std::accumulate(_items.begin(), _items.end(), 0.0);
return sum;
}

Но я получаю эту ошибку: error C2893: Failed to specialize function template 'unknown-type std::plus<void>::operator ()(_Ty1 &&,_Ty2 &&) const'

Важное замечание: класс Customer уже включает заголовок Item.

РЕДАКТИРОВАТЬ: Добавлена ​​информация об элементе класса.

2

Решение

Если предположить, Item это что-то вроде этого:

struct Item {
double price;
};

Тогда вы можете использовать следующее:

auto add_item_price = [](double sum, const Item& item) {
return sum + item.price;
};

double sum = std::accumulate(_items.begin(), _items.end(), 0.0, add_item_price);

Вот функциональная демоверсия.

Объяснение:

std::accumulate позволяет вам предоставить функцию / функтор, который будет выполнять накопление. Код, который я разместил, использует лямбда-функция сделать накопление. Если вы не используете C ++ 11, вы можете использовать обычную функцию вместо лямбда-функции.

Избегайте перегрузок operator+ за Item. Добавление двух Itemс не имеет особого смысла.

3

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

Эта ошибка обычно возникает, когда компилятор не знает, как накапливать ваш тип. т.е. надо знать как добавить Item тип.
Таким образом, вы должны перегрузить + оператор в вашем Item учебный класс.

Или вы должны предоставить 4-й аргумент binary_op

0

Вам необходимо указать operator+() для тебя Item тип.

Также обратите внимание, что вам нужно operator<() класть Item объекты в std::set потому что это ассоциативный контейнер, который должен уметь сравнивать его объекты:

#include <iostream>
#include <set>
#include <algorithm>

struct Item
{
Item(double price) : m_price(price) {}

friend double operator+(const Item &lhs, const Item &rhs)
{
return lhs.m_price + rhs.m_price;
}

friend double operator<(const Item &lhs, const Item &rhs)
{
return lhs.m_price < rhs.m_price;
}

double m_price;
};

int main ()
{
std::set<Item> _items;
_items.insert( Item(10) );
_items.insert( Item(20) );
double sum = std::accumulate(_items.begin(), _items.end(), 0.0);
std::cout << "Sum = " << sum << std::endl;
return 0;
}

Выход:

Sum = 30
0

Я единственный, кто думал об использовании простого цикла?

auto sum = 0.0;
for (const auto& item : items){
sum += item.m_price;
}

Вы можете спросить, что проще?

0

Ошибка, которую вы получаете от компилятора, не зная, как добавить два объекта типа Item вместе во время звонка std::accumulate.

Самое простое решение — использовать перегрузку std::accumulate это принимает четвертый параметр, который определяет лямбда-функтор, который будет использоваться вместо значения по умолчанию std::plus<T> функциональный объект.

double Customer::totalSum() const {
return std::accumulate(_items.begin(), _items.end(), 0.0,
[] (double previousValue, const auto& item) { // Called for every element.
return previousValue + item.totalPrice();
});
}

Другое решение заключается в создании настраиваемой перегрузки для operator+ это может добавить два Item объекты.

double operator+(const Item& lhs, const Item& rhs) {
return lhs.totalPrice() + rhs.totalPrice();
}

Это может, однако, быть немного запутанным, поскольку класс Item имеет несколько членов, которые являются числами, и не очевидно, как должно происходить добавление. Будьте особенно внимательны при перегрузке арифметических операторов.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector