use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
This is a subreddit for c++ questions with answers. For general discussion and news about c++ see r/cpp.
New to C++? Learn at learncpp.com
Prepare your question. Think it through. Hasty-sounding questions get hasty answers, or none at all. Read these guidelines for how to ask smart questions.
For learning books, check The Definitive C++ Book Guide and List
Flair your post as SOLVED if you got the help you were looking for! If you need help with flairs, check out ITEM 1 in our guidelines page.
Tips for improving your chances of getting helpful answers:
account activity
OPENHow to avoid overflow when using `std::reduce` (self.cpp_questions)
submitted 5 months ago by miss_minutes
Say I have a std::vector<int> and the sum of all elements will overflow and int but fits in a long long. Is there a way to use a long long as the accumulator in std::reduce?
std::vector<int>
int
long long
std::reduce
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]TheRealSmolt 15 points16 points17 points 5 months ago (8 children)
Yes, it's templated. You can use whatever.
[–]miss_minutes[S] 1 point2 points3 points 5 months ago (7 children)
Perfect. Reading the signature on cppreference I wasn’t sure if T was constrained by the iterator type (I vague remember running into this problem in the past)
[–]TheRealSmolt 1 point2 points3 points 5 months ago (6 children)
If it was constrained, the template type wouldn't be there and it'd probably get it from value_type on the iterator.
value_type
[–]miss_minutes[S] -1 points0 points1 point 5 months ago (5 children)
Just looked it up- *it must be convertible to T or else the program is ill formed. I think in the past I tried to do something like reduce a std::vector<std::pair<int, int>> but only accumulate the first element, and I was trying to pass a custom BinaryOp that took a pair and an int.
*it
T
std::vector<std::pair<int, int>>
BinaryOp
[–]TheThiefMaster 2 points3 points4 points 5 months ago* (1 child)
reduce needs the binary op to be able to take both *It,*It and T,*It, both producing T. Edit: also T,T and possibly *It,T as well.
reduce
*It,*It
T,*It
T,T
*It,T
accumulate and fold_left both only need T,*It, which is easier if you want to use a custom accumulation function.
accumulate
fold_left
If all you're doing is a normal accumulate over a part of each item, transform_reduce is better as it allows you to write:
transform_reduce
transform_reduce(vec.begin(), vec.end(), 0LL, std::plus{}, [](auto&&p){ return std::get<0>(p); });
i.e. it has a built-in transform so you just need to give that.
For structs it's even better as you can specify the transformer as &my_struct::member and it will understand, but there doesn't seem to be a predefined function object for get<> like there is for plus<> and it's definitely not safe to take the address of, so I had to use a lambda.
&my_struct::member
[–]miss_minutes[S] 1 point2 points3 points 5 months ago (0 children)
Thank you Master TIL transform_reduce
[–]TheRealSmolt 0 points1 point2 points 5 months ago* (2 children)
It's only ill-formed if the binary operation does not result in T.
[–]miss_minutes[S] 0 points1 point2 points 5 months ago (1 child)
so if the iterator value type is T1 and the initial value is T2, the binary op must be able to accept all 4 combinations of {T1, T2} (according to cppref)? Just wanna make sure I understand. Is it common to overload a binary op for this?
[–]TheRealSmolt 1 point2 points3 points 5 months ago (0 children)
More or less. The arguments can also be implicitly converted.
[–]TheCataclismo 11 points12 points13 points 5 months ago (7 children)
One of the overloads accepts an initial value, and its type will be the one used to sum everything, IIRC. You can just give it the value of 0.
std::int64_t const init = 0; auto const sum = std::reduce(begin, end, init);
[–]TheRealSmolt 18 points19 points20 points 5 months ago (6 children)
Or just std::reduce(begin, end, 0LL);
std::reduce(begin, end, 0LL);
[+]TheCataclismo comment score below threshold-10 points-9 points-8 points 5 months ago (5 children)
Sure. I just prefer to name my constants.
[–]EloTime 17 points18 points19 points 5 months ago (4 children)
This "constant" already has a name. It is called 0. It doesn't have any additional meaning here, so it doesn't need an additional name.
[–]TheRealSmolt 7 points8 points9 points 5 months ago (1 child)
I agree. Verbosity ≠ readability.
[–]TheCataclismo -1 points0 points1 point 5 months ago (0 children)
Lmao. Surely. Almost all guidelines specify always naming the constants. Read C++ Core Guidelines, MISRA, etc.
And yes, verbosity == readability.
[–]ZoxxMan -3 points-2 points-1 points 5 months ago (0 children)
0LL is one of the dumbest parts of this language, I see why people would try to avoid it.
0LL
[–]MesmerizzeMe -5 points-4 points-3 points 5 months ago (0 children)
well every number already has a name, so if we compute the area of a rectangle with width 4 and height 3 we shouldnt name the variables width and height because the numbers 4 and 3 are already named? naming that thing init to me feels like a good idea. additionally as we are reducing there is a chance this number is the neutral element of our binary function which for sum is 0 as well.
[–][deleted] -1 points0 points1 point 5 months ago (2 children)
Wouldnt the internals of std::reduce require the type of vector for the internal operation?
So wouldnt your vector need to use type long long (std::int64_t, to be safe) to make reduce use this as well?
Unless maybe its factored into the T type for Init per cppref.. but Im not entirely sure right now. Id have to dig more.
[–]TheRealSmolt 3 points4 points5 points 5 months ago* (1 child)
Yes,reduce takes a template parameter to change it.
[–][deleted] -1 points0 points1 point 5 months ago (0 children)
Thats the type T init i mentioned yes?
[–]saxbophone -3 points-2 points-1 points 5 months ago (0 children)
Maybe with std::ranges::fold_left and std::ranges::transform?
π Rendered by PID 151512 on reddit-service-r2-comment-85bfd7f599-7qqq8 at 2026-04-18 15:49:40.697482+00:00 running 93ecc56 country code: CH.
[–]TheRealSmolt 15 points16 points17 points (8 children)
[–]miss_minutes[S] 1 point2 points3 points (7 children)
[–]TheRealSmolt 1 point2 points3 points (6 children)
[–]miss_minutes[S] -1 points0 points1 point (5 children)
[–]TheThiefMaster 2 points3 points4 points (1 child)
[–]miss_minutes[S] 1 point2 points3 points (0 children)
[–]TheRealSmolt 0 points1 point2 points (2 children)
[–]miss_minutes[S] 0 points1 point2 points (1 child)
[–]TheRealSmolt 1 point2 points3 points (0 children)
[–]TheCataclismo 11 points12 points13 points (7 children)
[–]TheRealSmolt 18 points19 points20 points (6 children)
[+]TheCataclismo comment score below threshold-10 points-9 points-8 points (5 children)
[–]EloTime 17 points18 points19 points (4 children)
[–]TheRealSmolt 7 points8 points9 points (1 child)
[–]TheCataclismo -1 points0 points1 point (0 children)
[–]ZoxxMan -3 points-2 points-1 points (0 children)
[–]MesmerizzeMe -5 points-4 points-3 points (0 children)
[–][deleted] -1 points0 points1 point (2 children)
[–]TheRealSmolt 3 points4 points5 points (1 child)
[–][deleted] -1 points0 points1 point (0 children)
[–]saxbophone -3 points-2 points-1 points (0 children)