2

我试图找到集合中元素的总和,我想知道找到它的好方法是什么。我构建了两个类,一个称为 Customer,一个称为 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 的标题。

编辑:添加了关于类项目的信息。

4

5 回答 5

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 函数来进行累积。如果您不使用 C++11,则可以使用常规函数而不是 lambda 函数。

operator+Item避免重载. 添加两个Items 没有多大意义。

于 2016-01-16T20:05:35.910 回答
0

您从编译器得到的错误结果不知道如何Item在调用std::accumulate.

最简单的解决方案是使用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有多个数字成员,并且不清楚应该如何进行加法。重载算术运算符时要格外小心。

于 2016-01-16T20:19:45.403 回答
0

我是唯一一个想过使用简单循环的人吗?

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

你能问比这更简单的吗?

于 2016-01-16T20:21:45.653 回答
0

您需要operator+()为您的Item类型指定一个。

另请注意,您需要operator<()Item对象放入 an中,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
于 2016-01-16T20:13:02.773 回答
0

当编译器不知道如何累积您的类型时,通常会发生此错误。即它应该知道如何添加Item类型。所以你应该+在你的Item类中重载运算符。
或者你必须提供第四个参数binary_op

于 2016-01-16T20:02:07.740 回答