我试图找到一组中的元素总和,我想知道找到它的好方法是什么。 我构建了两个类,一个名为Customer,一个名为Item,我想编写一个函数来计算客户需要为类型Item中的std :: set中列出的产品支付的总付款。 这是我的集合的解除:
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的标题。
编辑:添加了有关课程项目的信息。
答案 0 :(得分:3)
假设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
允许您提供将执行累积的函数/函子。我发布的代码使用lambda function进行累积。如果您没有使用C ++ 11,则可以使用常规函数而不是lambda函数。
避免operator+
的Item
超载。添加两个Item
并没有多大意义。
答案 1 :(得分:0)
当编译器不知道如何累积您的类型时,通常会发生此错误。即它应该知道如何添加Item
类型。
因此,您应该在+
课程中重载Item
运算符。
或者你必须提供第四个参数binary_op
答案 2 :(得分: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
答案 3 :(得分:0)
由于编译器在调用std::accumulate
期间不知道如何将两个Item
类型的对象一起添加而导致错误。
最简单的解决方案是使用std::accumulate
的重载,它接受第四个参数,指定一个lambda仿函数来代替默认的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
有多个成员是数字,并且不应该如何进行添加。重载算术运算符时要特别小心。
答案 4 :(得分:0)
我是唯一一个考虑使用简单循环的人吗?
auto sum = 0.0;
for (const auto& item : items){
sum += item.m_price;
}
你可以问一下比这简单吗?