schrödinbug
schrödinbug

Reputation: 863

Find minimum element based on a transformed value

I have a std::vector of geometry vectors that I want to find the vector with the minimum norm. I can do it with std::minimum_element but that results in twice as many norm calculations as what are actually needed. Very similar to these questions:

Finding minimum element based on a transformed value

Saving function evaluations while using std::min_element()

Neither of which have a satisfactory answer. Using the possible implementations for std::minimum_element and std::transform for inspiration I came up with:

template<class ForwardIt, class UnaryOperation, class XformT = double>
ForwardIt min_transformed_element(ForwardIt first, ForwardIt last, UnaryOperation unary_op)
{
    if (first == last) return last;

    ForwardIt smallest = first;
    XformT smallest_val = unary_op(*first);

    ++first;
    for (; first != last; ++first) {
        XformT first_val = unary_op(*first);
        if (first_val < smallest_val) {
            smallest = first;
            smallest_val = first_val;
        }
    }
    return smallest;
}

which works fantastic. The only thing I don't like is how the type for XformT is specified. The compiler can't deduce it, so as a hack, I gave it the default type. Is there a better way to have it specified or deduced?

Example of it running is here: https://wandbox.org/permlink/Mvr69yFIMtxQB7yy

Upvotes: 0

Views: 82

Answers (1)

Joel
Joel

Reputation: 361

Use auto:

template<class ForwardIt, class UnaryOperation>
ForwardIt min_transformed_element(ForwardIt first, ForwardIt last, UnaryOperation unary_op)
{
    if (first == last) return last;

    ForwardIt smallest = first;
    auto smallest_val = unary_op(*first);

    ++first;
    for (; first != last; ++first) {
        auto first_val = unary_op(*first);
        if (first_val < smallest_val) {
            smallest = first;
            smallest_val = first_val;
        }
    }
    return smallest;
}

Upvotes: 1

Related Questions