Reputation: 123
I have Example Class:
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; }
};
In source code I have std::vector of Example Objects.
Is it possible with some std::algorithm, std::numeric functions make a sum of Value1 of all Obejcts in vector
something like this: std::accumulate(vector.begin(), vector.end(), 0, SomeFunctorOrOthers)....
Of course I can use an iterators... but if it is possible ii want to know it
Thank you very much!
Upvotes: 6
Views: 6147
Reputation: 3543
int sum =
std::transform_reduce(v.begin(), v.end(), 0, std::plus<>(),
[](const Object& o) { return o.getValue1(); });
Use ranges::views::transform
(C++20), and ranges::fold_left
(C++23)
auto values = v | std::ranges::views::transform([](const Object& o) { return o.getValue1(); });
int sum = std::ranges::fold_left(values, 0, std::plus<>{});
// int sum = std::accumulate(values.begin(), values.end(), 0); // C++20
Upvotes: 1
Reputation: 56479
std::accumulate(v.begin(), v.end(), 0);
It's enough if you overload operator casting for int
:
class Example {
...
operator int() { return testValue1; }
};
The drawback is, you may don't want this overload generally applies in your class.
Upvotes: 1
Reputation: 55395
Sure:
int sum =
std::accumulate (begin(v), end(v), 0,
[](int i, const Object& o){ return o.getValue1() + i; });
Note that, since Object
is passed by const-ref to the lambda, you need to make getters const
(that's a good practice anyway).
If you don't have C++11, you can define a functor with overloaded operator()
. I'd go further and make it a template so you can easily decide which of the getters you'd like to call:
template<int (Object::* P)() const> // member function pointer parameter
struct adder {
int operator()(int i, const Object& o) const
{
return (o.*P)() + i;
}
};
Pass it like this to algorithm: adder<&Object::getValue2>()
Upvotes: 14
Reputation: 1526
std::accumulate(vector.begin(), vector.end(), 0, [](const int& a, Example& b)
{
return a + b.getValue1();
});
Upvotes: 3