Hello Dear Jonathan, Could you answer the following 3 questions please? (1) For all cases where an STL predicate "pred" will suffice, e.g. your example using std::greater<>, is there any case where std::max_element(b, e, pred) would not also perform the job? Apart from the issue of code bloat, performance would seem better with std::maximum(), because there would be no function call in the inner loop. (Most if not all std predicates inline cleanly. With Borland compilers at least, function calls do not inline if they contain "if" statements. That is why select_by_predicate<> would result in an inner loop function call.) (2) For those cases where there is no suitable std predicate, you must have a custom predicate. In all such cases, is there any in which the call std::max_element(b,e, custom_pred) would not perform suitably? In this case let us ignore the performance issue. I only want to know if any new functionality has been added by introducing select_by_predicate<>. (3) I suppose your functor select_by_predicate<> has "state" between calls which retains a pointer to the last element which evaluated true. I suppose that pointer is initialized to NULL, and thats how the functor knows which is the first call. When the pointer is not NULL it compares the elements and resets the pointer if true. Below is the code for max_element from my Borland-Rouge Wave STL library. Note that max_element keep a copy of the best iterator, because it has access to the iterators, whereas select_by_predicate<> does not. I said I "suppose" your functor uses a pointer . But I don't know that for certain. That means I have to worry about whether "ForwardIterator::value_type::operator=" might be called. If I am not totally familiar with select_by_predicate<>, that means I either have to avoid any situation where "ForwardIterator::value_type::operator=" would be dangerous, or be prepared to open the doc page to double check. Do you think this is a valid issue? ============================ template <class ForwardIterator, class Compare> ForwardIterator max_element (ForwardIterator first, ForwardIterator last, Compare _RWSTD_COMP) { if (first == last) return first; ForwardIterator result = first; while (++first != last) if (_RWSTD_COMP(*result, *first)) result = first; return result; } ============================= Respecfully Yours Craig Hicks Engineer, KGK, Tokyo Jonathan Brownell wrote:
I work in doing programming involving quite a bit of data analysis, and lately I've gotten sick and tired of doing routine searches on vectors and other linear containers to pull out maximum/minimum values. I ended up sitting down and writing a unary function object that retains a value based on any predicate. An example is worth a thousand words:
int array[10] = { 5, 4, 6, 3, 9, 0, 7, 2, 8, 1 };
int maximum = std::for_each(&array[0], &array[10], select_by_predicate<int, std::greater>());
int minimum = std::for_each(&array[0], &array[10], select_by_predicate<int, std::less>());
assert(maximum == 9 && minimum == 0);
Another example, using select_by_predicate independently:
select_by_predicate<int, std::greater> max_error(0);
for(loop through data samples) { double error; ... analyze data sample error ...
max_error.compare(error); // same as max_error(error) }
std::cout << "Maximum error: " << max_error;
Is select_by_predicate something that boost users would be interested in? It's been helpful to me in all kinds of contexts.
-Jonathan
Info: <http://www.boost.org> Wiki: <http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl> Unsubscribe: <mailto:boost-users-unsubscribe@yahoogroups.com>
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/