C++中std::vector<Object>成员的总和

6

我有一个示例类:

class Example {
private:
  int testValue1;
  int testValue2;
  int testValue3;

public:
  Example(int pVal1, int pVal2, int pVal3);

  Example(const Example);

  const Example operator =(const Example);

  inline int getValue1() { return testValue1; }

  inline int getValue2() { return testValue2; }

  inline int getValue3() { return testValue3; }

};

在源代码中,我有一个Example对象的std::vector。
使用一些std::algorithm和std::numeric函数,是否可以对向量中所有对象的Value1进行求和?
类似于这样: std::accumulate(vector.begin(), vector.end(), 0, SomeFunctorOrOthers)....
当然,我可以使用迭代器...但如果可能的话,我想知道它是否可行。
非常感谢!
3个回答

14

当然:

int sum = 
std::accumulate (begin(v), end(v), 0, 
    [](int i, const Object& o){ return o.getValue1() + i; });

请注意,由于Object被以const-ref的方式传递给lambda表达式,您需要将getter函数设置为const(这是一个好习惯)。

如果您没有使用C++11,您可以定义一个带有重载的operator()的函数对象。我建议将其制作成模板,这样您就可以轻松地决定要调用哪个getter函数:

template<int (Object::* P)() const> // member function pointer parameter
struct adder {
    int operator()(int i, const Object& o) const
    {
        return (o.*P)() + i;
    }  
};

将它像这样传递给算法:adder<&Object::getValue2>()


这里的 int i 是做什么的技巧? - Deepak Sharma
2
这是传递给lambda函数的第一个参数。'accumulate'算法使用它来传递运行总和。 - jrok

3
std::accumulate(vector.begin(), vector.end(), 0, [](const int& a, Example& b)
{
return a + b.getValue1();
});

如何使其在成员数据类型为浮点数时正常工作。 - reubenjohn

1
std::accumulate(v.begin(), v.end(), 0);

如果您为 int 重载运算符转换,那就足够了:

class Example {
  ...

  operator int()  { return testValue1; }
};

缺点是,你可能不希望这种过载通常适用于你的类。

5
我不认为这是提供像隐式转换为 int 这样通用(且危险)的东西的好理由。 - Björn Pollex
我个人不太喜欢这种方法,但这只是另一种方式。由于Example类只是一个示例,所以这个解决方案可能并不是真的很糟糕。 - masoud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接