I thought the following would work but it just outputs zero. Ideas?
std::vector<int> a = { 1, 2, 3 }; std::vector<int> b = { 4, 5, 6 }; int max = *std::max(std::max(a.begin(), a.end()), std::max(b.begin(), b.end())); std::cout << max; You're using std::max, which compares its arguments. That is, it's returning the greater of the two iterators.
What you want for the inner invocation is std::max_element, which finds the maximum element in a range:
std::vector<int> a = { 1, 2, 3 }; std::vector<int> b = { 4, 5, 6 }; int max = std::max(*std::max_element(a.begin(), a.end()), *std::max_element(b.begin(), b.end())); std::cout << max; As @MikeSeymour correctly pointed out in comments, the above code assumes the ranges are not empty, as it unconditionally dereferences the iterators returned from std::max_element. If one of the ranges was empty, the returned iterator would be the past-the-end one, which cannot be dereferenced.
Here's a way that behaves sensibly with empty ranges. If either range is empty, you still get the maximum from the other range. If both ranges are empty, you get INT_MIN.
auto op = [](int a, int b) { return std::max(a, b); }; // 1) int m = std::reduce(begin(b), end(b), std::reduce(begin(a), end(a), INT_MIN, op), op); std::reduce2) is better here, since you want a value, not an iterator as the result.
1) we need a lambda wrapper because we are not allowed to take the address of std::max
2) pre-C++-17, you can use std::accumulate
std::max. It doesn't take ranges.std::max_elementinstead.