Skip to main content
Code Review

Return to Question

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

I came across this SO question this SO question on why std::max_element requires a ForwardIterator (as apposed to an InputIterator). Having a max_element-like algorithm for InputIterator would be useful, as it could then be used with objects like std::istream_iterator or boost::transform_iterator.

I came up with the following algorithm for this:

#include <iterator> // std::iterator_traits, std::advance
#include <stdexcept> // std::logic_error
#include <algorithm> // std::for_each
#include <functional> // std::less
#include <utility> // std::move
template <typename InputIterator, typename Compare>
typename std::iterator_traits<InputIterator>::value_type
max_input(InputIterator first, InputIterator last, Compare comp)
{
 if (first == last) throw std::logic_error {"max_input given empty range"};
 
 using ValueType = typename std::iterator_traits<InputIterator>::value_type;
 
 ValueType result {*first};
 
 std::advance(first, 1);
 
 std::for_each(first, last, [&result, comp] (ValueType curr) {
 if (comp(result, curr)) result = std::move(curr);
 });
 
 return result;
}

Example:

#include <sstream>
#include <iostream>
int main()
{
 std::istringstream str("0.1 0.2 0.3 0.4 0.2 0.0 0.1");
 
 const auto max = max_input(std::istream_iterator<double>(str), std::istream_iterator<double>());
 
 std::cout << "max is " << max << std::endl;
 
 return 0;
}

I'm looking for general feedback/improvements, especially on the decision to throw for an empty range. I was also deliberating whether the algorithm should also return the index of the maximum (e.g. in a std::pair).

I came across this SO question on why std::max_element requires a ForwardIterator (as apposed to an InputIterator). Having a max_element-like algorithm for InputIterator would be useful, as it could then be used with objects like std::istream_iterator or boost::transform_iterator.

I came up with the following algorithm for this:

#include <iterator> // std::iterator_traits, std::advance
#include <stdexcept> // std::logic_error
#include <algorithm> // std::for_each
#include <functional> // std::less
#include <utility> // std::move
template <typename InputIterator, typename Compare>
typename std::iterator_traits<InputIterator>::value_type
max_input(InputIterator first, InputIterator last, Compare comp)
{
 if (first == last) throw std::logic_error {"max_input given empty range"};
 
 using ValueType = typename std::iterator_traits<InputIterator>::value_type;
 
 ValueType result {*first};
 
 std::advance(first, 1);
 
 std::for_each(first, last, [&result, comp] (ValueType curr) {
 if (comp(result, curr)) result = std::move(curr);
 });
 
 return result;
}

Example:

#include <sstream>
#include <iostream>
int main()
{
 std::istringstream str("0.1 0.2 0.3 0.4 0.2 0.0 0.1");
 
 const auto max = max_input(std::istream_iterator<double>(str), std::istream_iterator<double>());
 
 std::cout << "max is " << max << std::endl;
 
 return 0;
}

I'm looking for general feedback/improvements, especially on the decision to throw for an empty range. I was also deliberating whether the algorithm should also return the index of the maximum (e.g. in a std::pair).

I came across this SO question on why std::max_element requires a ForwardIterator (as apposed to an InputIterator). Having a max_element-like algorithm for InputIterator would be useful, as it could then be used with objects like std::istream_iterator or boost::transform_iterator.

I came up with the following algorithm for this:

#include <iterator> // std::iterator_traits, std::advance
#include <stdexcept> // std::logic_error
#include <algorithm> // std::for_each
#include <functional> // std::less
#include <utility> // std::move
template <typename InputIterator, typename Compare>
typename std::iterator_traits<InputIterator>::value_type
max_input(InputIterator first, InputIterator last, Compare comp)
{
 if (first == last) throw std::logic_error {"max_input given empty range"};
 
 using ValueType = typename std::iterator_traits<InputIterator>::value_type;
 
 ValueType result {*first};
 
 std::advance(first, 1);
 
 std::for_each(first, last, [&result, comp] (ValueType curr) {
 if (comp(result, curr)) result = std::move(curr);
 });
 
 return result;
}

Example:

#include <sstream>
#include <iostream>
int main()
{
 std::istringstream str("0.1 0.2 0.3 0.4 0.2 0.0 0.1");
 
 const auto max = max_input(std::istream_iterator<double>(str), std::istream_iterator<double>());
 
 std::cout << "max is " << max << std::endl;
 
 return 0;
}

I'm looking for general feedback/improvements, especially on the decision to throw for an empty range. I was also deliberating whether the algorithm should also return the index of the maximum (e.g. in a std::pair).

added 58 characters in body
Source Link
Daniel
  • 825
  • 2
  • 8
  • 15

I came across this SO question on why std::max_elementstd::max_element requires a ForwardIterator (as apposed to an InputIterator). Having a max_element-like algorithm for InputIterator would be useful, as it could then be used with objects like std::istream_iterator or boost::transform_iterator.

I came up with the following algorithm for this:

#include <iterator> // std::iterator_traits, std::advance
#include <stdexcept> // std::logic_error
#include <algorithm> // std::for_each
#include <functional> // std::less
#include <utility> // std::move
template <typename InputIterator, typename Compare>
typename std::iterator_traits<InputIterator>::value_type
max_input(InputIterator first, InputIterator last, Compare comp)
{
 if (first == last) throw std::logic_error {"max_input given empty range"};
 
 using ValueType = typename std::iterator_traits<InputIterator>::value_type;
 
 ValueType result {*first};
 
 std::advance(first, 1);
 
 std::for_each(first, last, [&result, comp] (ValueType curr) {
 if (comp(result, curr)) result = std::move(curr);
 });
 
 return result;
}

Example:

#include <sstream>
#include <iostream>
int main()
{
 std::istringstream str("0.1 0.2 0.3 0.4 0.2 0.0 0.1");
 
 const auto max = max_input(std::istream_iterator<double>(str), std::istream_iterator<double>());
 
 std::cout << "max is " << max << std::endl;
 
 return 0;
}

I'm looking for general feedback/improvements, especially on the decision to throw for an empty range. I was also deliberating whether the algorithm should also return the index of the maximum (e.g. in a std::pair).

I came across this SO question on why std::max_element requires a ForwardIterator (as apposed to an InputIterator). Having a max_element-like algorithm for InputIterator would be useful, as it could then be used with objects like std::istream_iterator or boost::transform_iterator.

I came up with the following algorithm for this:

#include <iterator> // std::iterator_traits, std::advance
#include <stdexcept> // std::logic_error
#include <algorithm> // std::for_each
#include <functional> // std::less
#include <utility> // std::move
template <typename InputIterator, typename Compare>
typename std::iterator_traits<InputIterator>::value_type
max_input(InputIterator first, InputIterator last, Compare comp)
{
 if (first == last) throw std::logic_error {"max_input given empty range"};
 
 using ValueType = typename std::iterator_traits<InputIterator>::value_type;
 
 ValueType result {*first};
 
 std::advance(first, 1);
 
 std::for_each(first, last, [&result, comp] (ValueType curr) {
 if (comp(result, curr)) result = std::move(curr);
 });
 
 return result;
}

Example:

#include <sstream>
#include <iostream>
int main()
{
 std::istringstream str("0.1 0.2 0.3 0.4 0.2 0.0 0.1");
 
 const auto max = max_input(std::istream_iterator<double>(str), std::istream_iterator<double>());
 
 std::cout << "max is " << max << std::endl;
 
 return 0;
}

I'm looking for general feedback/improvements, especially on the decision to throw for an empty range. I was also deliberating whether the algorithm should also return the index of the maximum (e.g. in a std::pair).

I came across this SO question on why std::max_element requires a ForwardIterator (as apposed to an InputIterator). Having a max_element-like algorithm for InputIterator would be useful, as it could then be used with objects like std::istream_iterator or boost::transform_iterator.

I came up with the following algorithm for this:

#include <iterator> // std::iterator_traits, std::advance
#include <stdexcept> // std::logic_error
#include <algorithm> // std::for_each
#include <functional> // std::less
#include <utility> // std::move
template <typename InputIterator, typename Compare>
typename std::iterator_traits<InputIterator>::value_type
max_input(InputIterator first, InputIterator last, Compare comp)
{
 if (first == last) throw std::logic_error {"max_input given empty range"};
 
 using ValueType = typename std::iterator_traits<InputIterator>::value_type;
 
 ValueType result {*first};
 
 std::advance(first, 1);
 
 std::for_each(first, last, [&result, comp] (ValueType curr) {
 if (comp(result, curr)) result = std::move(curr);
 });
 
 return result;
}

Example:

#include <sstream>
#include <iostream>
int main()
{
 std::istringstream str("0.1 0.2 0.3 0.4 0.2 0.0 0.1");
 
 const auto max = max_input(std::istream_iterator<double>(str), std::istream_iterator<double>());
 
 std::cout << "max is " << max << std::endl;
 
 return 0;
}

I'm looking for general feedback/improvements, especially on the decision to throw for an empty range. I was also deliberating whether the algorithm should also return the index of the maximum (e.g. in a std::pair).

edited tags; edited title
Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

max Max element of input iterator range

edited tags
Link
Daniel
  • 825
  • 2
  • 8
  • 15
Loading
added 29 characters in body
Source Link
Daniel
  • 825
  • 2
  • 8
  • 15
Loading
Source Link
Daniel
  • 825
  • 2
  • 8
  • 15
Loading
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /